The documentation for "Pimpl with Value Semantics" has: "and was deployed in the previous chapter for the Pimpls with pointer semantics..." but there is no previous chapter about Pimpl with pointer semantics. From that point on the documentation of "Pimpl with Value Semantics makes no sense to me and I do not know what is being explained.
On 06/06/2014 09:27 AM, Edward Diener wrote:
The documentation for "Pimpl with Value Semantics" has:
"and was deployed in the previous chapter for the Pimpls with pointer semantics..."
but there is no previous chapter about Pimpl with pointer semantics. From that point on the documentation of "Pimpl with Value Semantics makes no sense to me and I do not know what is being explained.
Yes, the chapter you are referring to says "/std::shared_ptr/ ... was deployed in the previous chapter". The previous chapter is called "Getting Started". It says "we would like ... a /Pimpl/-style class with the /pointer semantics/. That is:". Then it goes on to explain what Pimpl with /pointer semantics /is and how shared_ptr plays a role there. Still, I'll try to re-phrase the chapters to clarify. Thank you, Edward.
On 6/5/2014 7:53 PM, Vladimir Batov wrote:
On 06/06/2014 09:27 AM, Edward Diener wrote:
The documentation for "Pimpl with Value Semantics" has:
"and was deployed in the previous chapter for the Pimpls with pointer semantics..."
but there is no previous chapter about Pimpl with pointer semantics. From that point on the documentation of "Pimpl with Value Semantics makes no sense to me and I do not know what is being explained.
Yes, the chapter you are referring to says "/std::shared_ptr/ ... was deployed in the previous chapter". The previous chapter is called "Getting Started". It says "we would like ... a /Pimpl/-style class with the /pointer semantics/. That is:". Then it goes on to explain what Pimpl with /pointer semantics /is and how shared_ptr plays a role there. Still, I'll try to re-phrase the chapters to clarify. Thank you, Edward.
I think you need to explain what the actual pimpl class template is and does before jumping in with examples that use it. I do admit I am a person who is nearly incapable of using software based largely on examples rather than on actual well-explained concepts and interface details.
On 06/06/2014 11:29 AM, Edward Diener wrote:
On 6/5/2014 7:53 PM, Vladimir Batov wrote:
On 06/06/2014 09:27 AM, Edward Diener wrote:
The documentation for "Pimpl with Value Semantics" has:
"and was deployed in the previous chapter for the Pimpls with pointer semantics..."
but there is no previous chapter about Pimpl with pointer semantics. From that point on the documentation of "Pimpl with Value Semantics makes no sense to me and I do not know what is being explained.
Yes, the chapter you are referring to says "/std::shared_ptr/ ... was deployed in the previous chapter". The previous chapter is called "Getting Started". It says "we would like ... a /Pimpl/-style class with the /pointer semantics/. That is:". Then it goes on to explain what Pimpl with /pointer semantics /is and how shared_ptr plays a role there. Still, I'll try to re-phrase the chapters to clarify. Thank you, Edward.
I think you need to explain what the actual pimpl class template is and does before jumping in with examples that use it.
Thanks, Edward. I'll try to re-do the relevant parts as you suggest. Won't do in in a hurry though remembering my experience with "convert", right? :-)
I do admit I am a person who is nearly incapable of using software based largely on examples rather than on actual well-explained concepts and interface details.
Aha, I suspect you are over 20y.o., aren't you? :-) Down here I sometime deal with uni students (practice placement) -- they expect everything to be explained in the Introduction. I kid you not, I had a case when a student (well, a young employee) need to lean C++, was given a C++ book to read and then he came back saying -- "I read the Intro, I more/less(?) understand what it's about. Where do I go from here?" :-) Anyway, I'll re-work the docs.
On June 5, 2014 10:08:15 PM EDT, Vladimir Batov
I'll try to re-do the relevant parts as you suggest. Won't do in in a hurry though remembering my experience with "convert", right? :-)
Since the review hasn't started, change all you like. ___ Rob (Sent from my portable computation engine)
-----Original Message----- From: Boost [mailto:boost-bounces@lists.boost.org] On Behalf Of Rob Stewart Sent: 06 June 2014 03:55 To: boost@lists.boost.org Subject: Re: [boost] [pimpl] No documentation for pointer semantics
On June 5, 2014 10:08:15 PM EDT, Vladimir Batov
wrote: I'll try to re-do the relevant parts as you suggest. Won't do in in a hurry though remembering my experience with "convert", right? :-)
Since the review hasn't started, change all you like.
I unhappy with a review rigid policy that nothing can be changed during a review. It isn't always helpful. We never accept anything without requiring some changes? Can we instead now use git's easy branches to specify a fixed 'master' branch, but allow the author to update a 'develop' branch as the review develops? That way typos and more serious mistakes can be corrected as the review proceeds. This will avoid people being confused by these. Paul --- Paul A. Bristow Prizet Farmhouse Kendal UK LA8 8AB +44 01539 561830
On June 6, 2014 4:51:36 AM EDT, "Paul A. Bristow"
-----Original Message----- From: Boost [mailto:boost-bounces@lists.boost.org] On Behalf Of Rob Stewart Sent: 06 June 2014 03:55 To: boost@lists.boost.org Subject: Re: [boost] [pimpl] No documentation for pointer semantics
On June 5, 2014 10:08:15 PM EDT, Vladimir Batov
wrote: I'll try to re-do the relevant parts as you suggest. Won't do in in a hurry though remembering my experience with
"convert",
right? :-)
Since the review hasn't started, change all you like.
I unhappy with a review rigid policy that nothing can be changed during a review. It isn't always helpful.
The policy is that the material under review must not change during the review. There's no policy against providing a copy that reflects ongoing changes. Vladimir began to do just that during the Boost.Convert review.
Can we instead now use git's easy branches to specify a fixed 'master' branch, but allow the author to update a 'develop' branch as the review develops?
Sure ___ Rob (Sent from my portable computation engine)
On 6 Jun 2014 at 9:51, Paul A. Bristow wrote:
Since the review hasn't started, change all you like.
I unhappy with a review rigid policy that nothing can be changed during a review. It isn't always helpful.
We never accept anything without requiring some changes?
Can we instead now use git's easy branches to specify a fixed 'master' branch, but allow the author to update a 'develop' branch as the review develops?
That way typos and more serious mistakes can be corrected as the review proceeds. This will avoid people being confused by these.
AFIO has a special 'boost-peer-review' branch (https://github.com/BoostGSoC13/boost.afio/tree/boost-peer-review) intended for peer review. Said branch is the most stable of all stable branches. I would avoid using master branch, as sometimes you need to change master branch because other projects you depend on have changed. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
On 6/6/2014 4:51 AM, Paul A. Bristow wrote:
-----Original Message----- From: Boost [mailto:boost-bounces@lists.boost.org] On Behalf Of Rob Stewart Sent: 06 June 2014 03:55 To: boost@lists.boost.org Subject: Re: [boost] [pimpl] No documentation for pointer semantics
On June 5, 2014 10:08:15 PM EDT, Vladimir Batov
wrote: I'll try to re-do the relevant parts as you suggest. Won't do in in a hurry though remembering my experience with "convert", right? :-)
Since the review hasn't started, change all you like.
I unhappy with a review rigid policy that nothing can be changed during a review. It isn't always helpful.
We never accept anything without requiring some changes?
Can we instead now use git's easy branches to specify a fixed 'master' branch, but allow the author to update a 'develop' branch as the review develops?
I believe that changes can be made to a reviewed library during a review as long as the 'master' branch does not change. After all we want all reviewers to be looking at the same 'master' branch as the code to be reviewed. But if the developer wants to make changes to other branches during the review I think this should be allowed.
That way typos and more serious mistakes can be corrected as the review proceeds. This will avoid people being confused by these.
On 6/06/2014 11:27, quoth Edward Diener:
The documentation for "Pimpl with Value Semantics" has:
"and was deployed in the previous chapter for the Pimpls with pointer semantics..."
but there is no previous chapter about Pimpl with pointer semantics. From that point on the documentation of "Pimpl with Value Semantics makes no sense to me and I do not know what is being explained.
I believe the prior chapter being referred to is the directly prior chapter, titled "Getting Started", which shows a class implemented using pointer semantics. To be honest I'm a little surprised that pointer semantics are even discussed; I've always regarded a pointer-semantics-pimpl as a bug rather than intentional design. I suppose there could be occasions where it could be useful for more abstract resources (eg. a database connection) but doing it for a Book does not seem appropriate to me. (Perhaps that's just my internal biases showing though.)
Gavin, Gavin Lambert wrote
... To be honest I'm a little surprised that pointer semantics are even discussed; I've always regarded a pointer-semantics-pimpl as a bug rather than intentional design.
It's is amazing. I am really surprised to read that. Not in an angry way but in a really unexpected way. Andrzej shared your view and as strongly as well. I am so surprised because I am on the exactly opposite end -- I've been using that Pimpl-enabling "helper" class on a few big projects... exclusively with pointer-semantics.
I suppose there could be occasions where it could be useful for more abstract resources (eg. a database connection) ...
I am looking back and trying to figure out how my deployment was/is so different from what you and Andrzej would use Pimpl for. Now that I am thinking about it seems to always play a role of a (shared) handle to some big chunk of data. Not just bit chunk but mostly read-only and non-copyable. For example, a description of a railway track only makes sense when it has prev/next track references, i.e. it has to be accessed as part of the whole picture (railway network). So, for me the implementation-hiding property of Pimpl would always go hand-in-hand with the proxy/handle property... For some reason I always assumed many Handles in the Handle/Body idiom... which Pimpl is just another name for. Now that I am researching Handle/Body, Bridge they are about decoupling of an abstraction from its implementation. No explicit mention of "shareability" of the implementation. Seems like Rob was right saying I inadvertently "extended the idiom"... On the other hand all the Handle/Body, Bridge, etc. descriptions I've read so far indeed do not mention "shareability". However, they do not say that "shareability" is *not* part of the idiom either. To me it makes sense because Handles are cheap. So, having many Handles for one Body does not seem like such a huge leap. In that light, my offering of pimpl::pointer_semantics and pimpl::value_semantics seems to make sense.
... but doing it for a Book does not seem appropriate to me. (Perhaps that's just my internal biases showing though.)
What's so different about a Book? Imagine, we model a Library -- a collection of Books. Books are not copied around, instead references to the real and one only Book are passed around. That way if I try borrowing a Book, I'll access its actual data to see if it's available or, maybe, you beat me to it by borrowing it first via your reference. Sounds like our model corresponds quite closely to the real working of a library... which is usually a good thing, right? -- View this message in context: http://boost.2283326.n4.nabble.com/pimpl-No-documentation-for-pointer-semant... Sent from the Boost - Dev mailing list archive at Nabble.com.
On June 6, 2014 4:59:47 AM EDT, Vladimir Batov
I am looking back and trying to figure out how my deployment was/is so different from what [Gavin] and Andrzej would use Pimpl for. Now that I am thinking about it seems to always play a role of a (shared) handle to some big chunk of data. Not just bit chunk but mostly read-only and non-copyable.
There's nothing wrong with such an implementation.
So, for me the implementation-hiding property of Pimpl would always go hand-in-hand with the proxy/handle property...
That's where you go off-track, so to speak.
For some reason I always assumed many Handles in the Handle/Body idiom... which Pimpl is just another name for.
Another step away...
Now that I am researching Handle/Body, Bridge they are about decoupling of an abstraction from its implementation. No explicit mention of "shareability" of the implementation. Seems like Rob was right saying I inadvertently "extended the idiom"...
:)
On the other hand all the Handle/Body, Bridge, etc. descriptions I've read so far indeed do not mention "shareability". However, they do not say that "shareability" is *not* part of the idiom either. To me it makes sense because Handles are cheap.
Making such a lap is not a problem. Continuing to call what you're doing by the same name is the problem. What you're doing is COW, at least if writing the underlying data triggers a copy. (If not then I'd say you're providing a variation of the Flyweight Pattern.)
So, having many Handles for one Body does not seem like such a huge leap.
No, it doesn't.
In that light, my offering of pimpl::pointer_semantics and pimpl::value_semantics seems to make sense.
That's the problem. It isn't the Pimpl Idiom anymore. ___ Rob (Sent from my portable computation engine)
Rob Stewart-6 wrote
... On June 6, 2014 4:59:47 AM EDT, Vladimir Batov <
vb.mail.247@
> wrote:
... my offering of pimpl::pointer_semantics and pimpl::value_semantics seems to make sense.
That's the problem. It isn't the Pimpl Idiom anymore.
Well, that was a few nervous hours when I felt my familiar Pimpl world was crashing all around me... after looking closely it seems my "extended" interpretation of Pimpl to still be the Pimpl Idiom. :-) First, Pimpl == Handle/Body == Bridge. Now I open GoF pg. 151 -- the Bridge chapter. The Applicability section -- you want to share an implementation among multiple objects (perhaps using ref. counting). The Consequences section -- Hiding implementation details from clients. You can shield clients from implementation details, like the sharing of implementor objects and the accompanying ref. counting mechanism (if any). The Implementation section -- 3. Sharing implementors. In fact, the Implementation section goes as far as to call one-to-one relationship between Abstraction and Implementor a degenerate case of the Bridge pattern. I.e. Gof sees pimpl::pointer_semantics, a.k.a. "Bridge with Shared Implementation" to be the proper Bridge when pimpl::value_semantics to be a degenerate one... although I feel it's a "bridge" :-) to far. Do I get a cookie? :-) -- View this message in context: http://boost.2283326.n4.nabble.com/pimpl-No-documentation-for-pointer-semant... Sent from the Boost - Dev mailing list archive at Nabble.com.
On June 6, 2014 8:02:44 AM EDT, Vladimir Batov
Rob Stewart-6 wrote
... On June 6, 2014 4:59:47 AM EDT, Vladimir Batov <
vb.mail.247@
> wrote:
... my offering of pimpl::pointer_semantics and pimpl::value_semantics seems to make sense.
That's the problem. It isn't the Pimpl Idiom anymore.
Well, that was a few nervous hours when I felt my familiar Pimpl world was crashing all around me... after looking closely it seems my "extended" interpretation of Pimpl to still be the Pimpl Idiom. :-) First, Pimpl == Handle/Body == Bridge.
Assertion
Now I open GoF pg. 151 -- the Bridge chapter.
The Applicability section -- you want to share an implementation among multiple objects (perhaps using ref. counting).
[snip]
The Implementation section -- 3. Sharing implementors.
In fact, the Implementation section goes as far as to call one-to-one relationship between Abstraction and Implementor a degenerate case of the Bridge pattern.
I.e. Gof sees pimpl::pointer_semantics, a.k.a. "Bridge with Shared Implementation" to be the proper Bridge when pimpl::value_semantics to be a degenerate one... although I feel it's a "bridge" :-) to far.
Conclusion If one accepts the assertion that the Pimpl Idiom is the Bridge Pattern, the conclusion is appropriate. I don't accept the assertion. That is, the Pimpl Idiom is the degenerate case, but it isn't the same as the Bridge Pattern.
Do I get a cookie? :-)
If your proposed library is named Boost.Bridge, for example, both forms fit. I'd still provide a pimpl class template, however. ___ Rob (Sent from my portable computation engine)
Rob Stewart-6 wrote
On June 6, 2014 8:02:44 AM EDT, Vladimir Batov wrote:
Rob Stewart-6 wrote
...
On June 6, 2014 4:59:47 AM EDT, Vladimir Batov wrote: ... my offering of pimpl::pointer_semantics and pimpl::value_semantics seems to make sense.
That's the problem. It isn't the Pimpl Idiom anymore.
Well, that was a few nervous hours when I felt my familiar Pimpl world was crashing all around me... after looking closely it seems my "extended" interpretation of Pimpl to still be the Pimpl Idiom. :-) First, Pimpl == Handle/Body == Bridge.
Assertion ... Conclusion
If one accepts the assertion that the Pimpl Idiom is the Bridge Pattern, the conclusion is appropriate. I don't accept the assertion. That is, the Pimpl Idiom is the degenerate case, but it isn't the same as the Bridge Pattern.
Rob, if I understand correctly, you concede that my offering of "pointer_semantics" and "value_semantics" is appropriate *if* it was called "bridge" rather than "pimpl" because you assert that my-pimpl == bridge and real-pimpl == my-pimpl:value_semantics. In other words, "real pimpl is a subset of bridge, a coincidental bridge, a degenerate bridge", right? Here we have no choice but go and ask H. Sutter as it was him who popularized Pimpl and wrote quite a bit about it. 1) http://www.gotw.ca/publications/mill04.htm 2) http://www.gotw.ca/publications/mill05.htm#1 3) http://herbsutter.com/gotw/_101/ In #1 Sutter introduces Pimpl as "a special form of the handle/body idiom (what I call the Pimpl Idiom..."; Then in #2 he reiterates again that "This is a variant of the handle/body idiom." So far, it's not exactly clear who is correct in our interpretations of Pimpl because loosely "variant" might be interpreted as "subset"... although strictly speaking "variant" means "modified" (http://thesaurus.com). In earlier Sutter's writings I certainly find those constant references to the Bridge pattern quite unfortunate... *if* that similarity is purely incidental. Maybe it was done for educational purposes. And, indeed, in his later writings Sutter seems to drop mentioning Bridge and exclusively stressing Pimpl being the Compiler Firewall idiom. When I read Sutter's later writings on that topic (and I see you participating in the conversations), I can see where your convictions are coming from. He uses std::unique_ptr in his C++11 examples and in #3 even provides a "some sort of library helper" as a generalization of the idiom. It's hard for me to say if Sutter's later focus on the Compiler Firewall idiom using only value-semantics is for educational purposes (to avoid distractions) or he indeed shares your (strict) convictions. I must confess that, if I agree with your strict view/interpretation of Pimpl, then I'd personally find it quite disappointing that after all that talk and discussions and everything Pimpl turns out to be merely a degenerate Bridge... something GoF stated from the very beginning in 1994... i.e. what was all that fuss for 20 years? All that said, now I am beginning to wonder if that's a good idea to even try getting "my-pimpl" into Boost. There seems no clear interpretation (in our *collective* mind) of what Pimpl embodies, what is Pimpl and what is not. More so, from reading #3 I conclude that Sutter advocates a far(!) simpler deployment pattern than I am offering. IMO all that uncertainty and controversy do not bode well for the code wishing be a part of Boost. -- View this message in context: http://boost.2283326.n4.nabble.com/pimpl-No-documentation-for-pointer-semant... Sent from the Boost - Dev mailing list archive at Nabble.com.
Vladimir Batov wrote
On June 6, 2014 8:02:44 AM EDT, Vladimir Batov wrote:
Rob Stewart-6 wrote
...
On June 6, 2014 4:59:47 AM EDT, Vladimir Batov wrote: ... my offering of pimpl::pointer_semantics and pimpl::value_semantics seems to make sense.
That's the problem. It isn't the Pimpl Idiom anymore.
... it seems my "extended" interpretation of Pimpl to still be the Pimpl Idiom. :-) First, Pimpl == Handle/Body == Bridge. ... I don't accept the assertion. That is, the Pimpl Idiom is the degenerate case, but it isn't the same as the Bridge Pattern. ... Here we have no choice but go and ask H. Sutter as it was him who
Rob Stewart-6 wrote popularized Pimpl and wrote quite a bit about it.
1) http://www.gotw.ca/publications/mill04.htm 2) http://www.gotw.ca/publications/mill05.htm#1 3) http://herbsutter.com/gotw/_101/
In #1 Sutter introduces Pimpl as "a special form of the handle/body idiom (what I call the Pimpl Idiom..."; Then in #2 he reiterates again that "This is a variant of the handle/body idiom." ... When I read Sutter's later writings on that topic (and I see you participating in the conversations), ...
Reading Sutter's http://herbsutter.com/gotw/_100 I conclude that he is not of much help to resolve the matter. First he writes:
Class widget uses a variant of the handle/body idiom. As documented by Coplien [1], handle/body was described as being primarily useful for reference counting of a shared implementation, but it also has more general implementation-hiding uses. For convenience, from now on I’ll call widget the “visible class” and impl the “Pimpl class.” [2] One big advantage of this idiom is that it breaks compile-time dependencies... it’s often dubbed a “compilation firewall.”
Prefer to hold the Pimpl using a unique_ptr. It’s more efficient than using a shared_ptr, and correctly expresses the intent that
the Pimpl object should not be shared.
To me it reads "it's another application of the handle/body idiom but we focus on its other property so we call it pimpl". Then though Sutter indicates that: * * which is clearly a departure from the generic handle/body idiom. I suspect it is due to Sutter being too much of an educator here rather than actual developer (who would realize that sometimes Pimpl object needs to be shared). That said, I glanced over his pimpl::value_semantics generalization at http://herbsutter.com/gotw/_101/ and my first impression is quite positive. It's very lightweight and I find splitting one header in two (public and private) to be very sensible (ironically matching the handle/body concept). I myself routinely do that to implement pimpl-based hierarchies. In comparison my-pimpl offering looks quite heavy and old (given no C++11 facelift). More and more I feel my-pimpl is a few years late to the party, err... the review. -- View this message in context: http://boost.2283326.n4.nabble.com/pimpl-No-documentation-for-pointer-semant... Sent from the Boost - Dev mailing list archive at Nabble.com.
On June 7, 2014 5:43:14 AM EDT, Vladimir Batov
I glanced over his pimpl::value_semantics generalization at http://herbsutter.com/gotw/_101/ and my first impression is quite positive.
I like the idea, too.
It's very lightweight and I find splitting one header in two (public and private) to be very sensible (ironically matching the handle/body concept).
:)
I myself routinely do that to implement pimpl-based hierarchies. In comparison my-pimpl offering looks quite heavy and old (given no C++11 facelift). More and more I feel my-pimpl is a few years late to the party, err... the review.
There are many that will not have variadic templates for years, so the older approach can still offer value. That said, your library would be more complete with something like Herb's approach. ___ Rob (Sent from my portable computation engine)
On June 6, 2014 8:21:19 PM EDT, Vladimir Batov
Rob Stewart-6 wrote
If one accepts the assertion that the Pimpl Idiom is the Bridge
the conclusion is appropriate. I don't accept the assertion. That is,
Pattern, the
Pimpl Idiom is the degenerate case, but it isn't the same as the Bridge Pattern.
Rob, if I understand correctly, you concede that my offering of "pointer_semantics" and "value_semantics" is appropriate *if* it was called "bridge" rather than "pimpl" because you assert that my-pimpl == bridge and real-pimpl == my-pimpl:value_semantics. In other words, "real pimpl is a subset of bridge, a coincidental bridge, a degenerate bridge", right?
Yes. I should go re-read GoF's description of Bridge and Coplien's description of Handle/Body. It's been a lot of years since I last did so.
Here we have no choice but go and ask H. Sutter as it was him who popularized Pimpl and wrote quite a bit about it.
1) http://www.gotw.ca/publications/mill04.htm 2) http://www.gotw.ca/publications/mill05.htm#1 3) http://herbsutter.com/gotw/_101/
In #1 Sutter introduces Pimpl as "a special form of the handle/body idiom (what I call the Pimpl Idiom...";
Saying it's a special form already implies differentiation.
Then in #2 he reiterates again that "This is a variant of the handle/body idiom."
Ditto for "variant".
So far, it's not exactly clear who is correct in our interpretations of Pimpl because loosely "variant" might be interpreted as "subset"... although strictly speaking "variant" means "modified" (http://thesaurus.com). In earlier Sutter's writings I certainly find those constant references to the Bridge pattern quite unfortunate... *if* that similarity is purely incidental. Maybe it was done for educational purposes. And, indeed, in his later writings Sutter seems to drop mentioning Bridge and exclusively stressing Pimpl being the Compiler Firewall idiom.
I find no inconsistency or room for confusion. Pimpl implements a degenerate form of the Bridge Pattern, but it isn't the same as other variants of the pattern. Therefore, calling all variants by the name of one degenerate variant is the problem. [snip]
All that said, now I am beginning to wonder if that's a good idea to even try getting "my-pimpl" into Boost.
I've never shared the implementation of a class among instances, apart from COW or Flyweight contexts, to my knowledge. I'm uncertain whether your shared mode supports those better than, for example, shared_ptr or custom solutions, but that doesn't mean it isn't useful, since you've been using it for years. There seems no clear interpretation
(in our *collective* mind) of what Pimpl embodies, what is Pimpl and what is not. More so, from reading #3 I conclude that Sutter advocates a far(!) simpler deployment pattern than I am offering. IMO all that uncertainty and controversy do not bode well for the code wishing be a part of Boost.
As I noted before, if you name your library Bridge, and it offers both pimpl and, say, shared_bridge class templates, the functionality remains and the confusion is lessened (at least for those that have never associated sharing with Pimpl). You could go with bridge::value_semantics and bridge::pointer_semantics, if you really want to, but I don't think that's as nice. Then again, using aliases mean you can offer both. IOW, I suggest that you postpone the review, rework your library, and then offer it for review. ___ Rob (Sent from my portable computation engine)
Well, that was a few nervous hours when I felt my familiar Pimpl world was crashing all around me...
FWIW, the worldview around where I am is similar to yours - very natural to have common scaffolding for the two sorts of "compiler firewall" (to avoid using the word pimpl!) - those with value semantics and those with shared-const semantics. Your implementation seems a little better than ours - the semantics are right there in the base class name making it hard to miss for the user browsing the source. Pete
Pete, Thank you for chiming in in support. I felt surrounded and outnumbered... :-) Pete Bartlett-2 wrote
Well, that was a few nervous hours when I felt my familiar Pimpl world was crashing all around me...
FWIW, the worldview around where I am is similar to yours - very natural to have common scaffolding for the two sorts of "compiler firewall" (to avoid using the word pimpl!) - those with value semantics and those with shared-const semantics.
Indeed, in my mind having two sides of that "coin" is quite natural... and I feel Rob agrees with us on that... he is just "vehemently" against calling it "pimpl". It is only now that I realize how unfortunate that Pimpl name is... Never occurred to me before... The funny part wore off and all we are left with is confusion and disagreement on what it stands for. Unfortunately, I do not feel that comfortable with "compiler firewall" either as IMO it might be even more susceptible to strict interpretation.
Your implementation seems a little better than ours - the semantics are right there in the base class name making it hard to miss for the user browsing the source.
If you have your own idiom-generalization solution, do you think we might joing forces so to speak and to cherry-pick the best bits from the both variants and come up with something better/simpler?.. Unless the dead simple Sutter's version at http://herbsutter.com/gotw/_101/ indeed satisfies the need. -- View this message in context: http://boost.2283326.n4.nabble.com/pimpl-No-documentation-for-pointer-semant... Sent from the Boost - Dev mailing list archive at Nabble.com.
On 7/06/2014 12:54, quoth Vladimir Batov:
Indeed, in my mind having two sides of that "coin" is quite natural... and I feel Rob agrees with us on that... he is just "vehemently" against calling it "pimpl".
If it helps (I'm not sure that it will), to me "pimpl" implies value semantics (typically very thin and implemented via a bare pointer internally). If you wanted to share such an object then you would wrap a shared_ptr around the "outside" of the class; it wouldn't be part of the internals (and consumers of the class wouldn't need to care whether it was implemented with a pimpl or not). A "handle" is different; it implies pointer semantics and can either be directly shared or cheaply copied (where the copied handle points to the same underlying object as the original). Mutability is orthogonal, but I suspect it's a factor in the confusion of idioms -- from the sounds of it both Rob and myself are used to value-semantics mutable pimpls, while Pete and yourself are used to pointer-semantics immutable "handles". Where an object is immutable the differences between value and pointer semantics are very slight (from a behavioural perspective, ignoring performance). To put it another way: other than recompiling, adding or removing a pimpl from a class should be invisible to consumers of that class (just like any other change to private fields of a class). I can envisage this easily for value semantics; I have a harder time doing so for pointer semantics (as this seems like it would require changing consumer code more extensively, unless the original class was *already* using some kind of handle/body pattern).
On 06/10/2014 11:12 AM, Gavin Lambert wrote:
On 7/06/2014 12:54, quoth Vladimir Batov:
Indeed, in my mind having two sides of that "coin" is quite natural... and I feel Rob agrees with us on that... he is just "vehemently" against calling it "pimpl".
If it helps (I'm not sure that it will), to me "pimpl" implies value semantics (typically very thin and implemented via a bare pointer internally). If you wanted to share such an object then you would wrap a shared_ptr around the "outside" of the class; it wouldn't be part of the internals (and consumers of the class wouldn't need to care whether it was implemented with a pimpl or not).
A "handle" is different; it implies pointer semantics and can either be directly shared or cheaply copied (where the copied handle points to the same underlying object as the original).
Mutability is orthogonal, but I suspect it's a factor in the confusion of idioms -- from the sounds of it both Rob and myself are used to value-semantics mutable pimpls, while Pete and yourself are used to pointer-semantics immutable "handles". Where an object is immutable the differences between value and pointer semantics are very slight (from a behavioural perspective, ignoring performance).
To put it another way: other than recompiling, adding or removing a pimpl from a class should be invisible to consumers of that class (just like any other change to private fields of a class). I can envisage this easily for value semantics; I have a harder time doing so for pointer semantics (as this seems like it would require changing consumer code more extensively, unless the original class was *already* using some kind of handle/body pattern).
Gavin, Thank you for the explanations. I do understand them and it all sounds sensible. And your reasoning most likely would be my reasoning as well if I started looking at it from purely academic point of view. Namely, the Compiler Firewall (a.k.a. Pimpl) idiom hides the implementation and is only concerned with that. Full stop. Clean and simple concept. Then, everything you write follows. Like "other than recompiling, adding or removing a pimpl from a class should be invisible to consumers of that class". I am not arguing against that. All my rumblings were due to my immense surprise and not due to disagreement or inability to understand the value-semantics concept. In my case it's most likely because my interest in and development of my-pimpl has always been driven by the practical need. And it just happened that I never had a need to hide implementation of small, copyable, value-semantics classes. I would start hiding implementations of classes when they were getting big and/or outside of my control... and not easily or non copyable Say, database (in wide sense) records, GUI components. So that deployment pattern was firmly burnt in my brain... it might well be the specificity of the industry I am in as no-one in our dev. team asked for or deployed pimpl::value_semantics. :-) Nevertheless, thank you for your explanations all the same. V.
On 10/06/2014 14:15, quoth Vladimir Batov:
In my case it's most likely because my interest in and development of my-pimpl has always been driven by the practical need. And it just happened that I never had a need to hide implementation of small, copyable, value-semantics classes. I would start hiding implementations of classes when they were getting big and/or outside of my control... and not easily or non copyable Say, database (in wide sense) records, GUI components. So that deployment pattern was firmly burnt in my brain... it might well be the specificity of the industry I am in as no-one in our dev. team asked for or deployed pimpl::value_semantics. :-)
My use of Pimpl has also been driven by practical need -- the need to avoid recompiling 200+ source files when changing a tiny implementation detail of one class that happens to be used deep in the object graph. (Compiling can take quite a long time.) Though normally I just do it manually rather than using any framework -- which isn't to say that a framework might not be useful if I had one readily available. But the way you're phrasing things above still sounds to me like we're still coming at things from different perspectives. To me, any given instance of a class (eg. Book) is *always* a value, and has value semantics. This doesn't imply that it's small or copyable -- you can mark classes as movable only or non-copyable/movable. If something wants to have a reference to that instance (pointer semantics), then it declares a pointer, reference, or smart pointer instance that refers to the other object. (Note that a smart pointer is itself a value-semantics instance that happens to have pointer-semantics referring to another object as well.) It's left up to the consumer to decide what kind of pointer to use, based on how they plan to use it. On occasion I've made a class that mandates specific pointer-semantics only (usually because it uses shared_from_this()), but it does this by having a private constructor, deleted copy constructor, and a public factory method that returns a shared_ptr<X>, such that it's not possible to get a non-shared instance from outside. Internally it's still a value object. But the concept of referencing/pointing is separated from the class itself, which is where our perspectives differ, I think.
On June 10, 2014 4:15:42 AM EDT, Gavin Lambert
On 10/06/2014 14:15, quoth Vladimir Batov:
In my case it's most likely because my interest in and development of my-pimpl has always been driven by the practical need. And it just happened that I never had a need to hide implementation of small, copyable, value-semantics classes. I would start hiding implementations of classes when they were getting big and/or outside of my control... and not easily or non copyable Say, database (in wide sense) records, GUI components. So that deployment pattern was firmly burnt in my brain... it might well be the specificity of the industry I am in as no-one in our dev. team asked for or deployed pimpl::value_semantics. :-)
My use of Pimpl has also been driven by practical need -- the need to avoid recompiling 200+ source files when changing a tiny implementation
detail of one class that happens to be used deep in the object graph. (Compiling can take quite a long time.) Though normally I just do it manually rather than using any framework -- which isn't to say that a framework might not be useful if I had one readily available.
Another common use case of the Pimpl Idiom is to keep implementation details in a dynamic library (shared object or DLL) for dynamically loaded extensions. Still another is to hide platform specifics. (Chief among those would be avoiding the need to include windows.h.)
But the way you're phrasing things above still sounds to me like we're still coming at things from different perspectives.
To me, any given instance of a class (eg. Book) is *always* a value, and has value semantics. This doesn't imply that it's small or copyable --
you can mark classes as movable only or non-copyable/movable.
The Handle/Body Idiom provides a handle class that manages a pointer to an instance of an implementation class. Normally, multiple handle objects can refer to the same body object, so reference counting is implied. Pimpl is a degenerate case with only one handle per body.
If something wants to have a reference to that instance (pointer semantics), then it declares a pointer, reference, or smart pointer instance that refers to the other object. (Note that a smart pointer is itself a value-semantics instance that happens to have pointer-semantics referring to another object as well.) It's left up to the consumer to decide what kind of pointer to use, based on how they plan to use it.
Both approaches are appropriate.
On occasion I've made a class that mandates specific pointer-semantics only (usually because it uses shared_from_this()), but it does this by having a private constructor, deleted copy constructor, and a public factory method that returns a shared_ptr<X>, such that it's not possible to get a non-shared instance from outside. Internally it's still a value object.
Also valid, but not more so.
But the concept of referencing/pointing is separated from the class itself, which is where our perspectives differ, I think.
One library can support both, however. ___ Rob (Sent from my portable computation engine)
Gavin, I was planning on replying by Rob bit me to it pretty much expressing my view. My strong "attachment" to ref.-counted "Pimpl" is probably stems from the fact that I've always treated it as another/handier name for Handly/Body. Strangely, in all these years of deploying my-pimpl no one (including Sutter) "corrected" me on that... until now. On 06/10/2014 06:15 PM, Gavin Lambert wrote:
On 10/06/2014 14:15, quoth Vladimir Batov:
In my case it's most likely because my interest in and development of my-pimpl has always been driven by the practical need. And it just happened that I never had a need to hide implementation of small, copyable, value-semantics classes. I would start hiding implementations of classes when they were getting big and/or outside of my control... and not easily or non copyable Say, database (in wide sense) records, GUI components. So that deployment pattern was firmly burnt in my brain... it might well be the specificity of the industry I am in as no-one in our dev. team asked for or deployed pimpl::value_semantics. :-)
My use of Pimpl has also been driven by practical need -- the need to avoid recompiling 200+ source files when changing a tiny implementation detail of one class that happens to be used deep in the object graph. (Compiling can take quite a long time.) Though normally I just do it manually rather than using any framework -- which isn't to say that a framework might not be useful if I had one readily available.
But the way you're phrasing things above still sounds to me like we're still coming at things from different perspectives.
To me, any given instance of a class (eg. Book) is *always* a value, and has value semantics. This doesn't imply that it's small or copyable -- you can mark classes as movable only or non-copyable/movable.
If something wants to have a reference to that instance (pointer semantics), then it declares a pointer, reference, or smart pointer instance that refers to the other object. (Note that a smart pointer is itself a value-semantics instance that happens to have pointer-semantics referring to another object as well.) It's left up to the consumer to decide what kind of pointer to use, based on how they plan to use it.
On occasion I've made a class that mandates specific pointer-semantics only (usually because it uses shared_from_this()), but it does this by having a private constructor, deleted copy constructor, and a public factory method that returns a shared_ptr<X>, such that it's not possible to get a non-shared instance from outside. Internally it's still a value object.
But the concept of referencing/pointing is separated from the class itself, which is where our perspectives differ, I think.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (8)
-
Edward Diener
-
Gavin Lambert
-
Niall Douglas
-
Paul A. Bristow
-
Pete Bartlett
-
Rob Stewart
-
Vladimir Batov
-
Vladimir Batov