[scope_guard] Naming roundup

So, there was a really interesting and hot discussion about namings. Many opinions were expressed and I'd like to make some roundup. These are the variants looked most suitable to me as the names of status modification functions: - arm/disarm. Although, noone have said anything about them, they are still in the current implementation and look quite applicable. - activate/deactivate (enable/disable). Other synonims for arm/disarm, a bit longer though. - on/off. The most laconic form. Though, these are not verbs as usually used for functions. One might think they are some getter functions. - guard/dismiss. On the on hand, the commonly used "dismiss" should look familiar. On the other, its meaning is too strong in regard of the function semantic. The "guard" may be used as well but the word is already frequently used. Besides, the guard's status enum values' names propably won't corellate with these words (I just don't see the active status name with root "guard" - guard::guarding? :( ). The other versions looked less reflective to me so I didn't include them in the list. I would be glad if you just vote for one of these positions to take the final decision. The make_guarded_call function name seems does not attract that much attention, so I shall leave it be. Besides, it it possible that I even remove it from the library, because it can be easily replaced by explicit "do" functor call and make_guard followed by it. Unfortunately, nearly no attention have been paid to the implementation itself, so there's nothing much to roundup here. PS: Still the question about checking in the library is arisen. The naming changes are 5 minutes worth, so the final version will be available very soon with almost no code changes. Will someone want to make a code revision or may I just gain access and checkin?

Andrey Semashev wrote:
So, there was a really interesting and hot discussion about namings. Many opinions were expressed and I'd like to make some roundup.
I still think that the question "should X be included at all" is slightly more fundamental than "should X be named rearm, protect, or on". But this may be just me.

"Peter Dimov" <pdimov@mmltd.net> writes:
Andrey Semashev wrote:
So, there was a really interesting and hot discussion about namings. Many opinions were expressed and I'd like to make some roundup.
I still think that the question "should X be included at all" is slightly more fundamental than "should X be named rearm, protect, or on". But this may be just me.
It's not _just_ you. I definitely agree. Why hasn't Peter's question been addressed? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
"Peter Dimov" <pdimov@mmltd.net> writes:
Andrey Semashev wrote:
So, there was a really interesting and hot discussion about namings. Many opinions were expressed and I'd like to make some roundup.
I still think that the question "should X be included at all" is slightly more fundamental than "should X be named rearm, protect, or on". But this may be just me.
It's not _just_ you. I definitely agree. Why hasn't Peter's question been addressed?
I guess I've missed it somewhere in the thread. I have given the example in the post nearby.

Peter Dimov wrote:
Andrey Semashev wrote:
So, there was a really interesting and hot discussion about namings. Many opinions were expressed and I'd like to make some roundup.
I still think that the question "should X be included at all" is slightly more fundamental than "should X be named rearm, protect, or on". But this may be just me.
I'm sorry I didn't answer directly to you, but I wrote this in one of the descussion threads: The more common use case is to create initially disabled guard and then, depending on some condition, activate it. I've had the need of such functionality several times. The example may be made up. Imagine we have some function that plays the role of a common entry point that dispatches objects of different types. For simplicity all objects support interface IObject that have a method GetType. The objects should be dispatched to different another entities depending on their type. But for some objects some post-actions should be made. void Entry(IObject* pObj) { scope_guard g = make_guard(&PostActions, guard::disarmed); switch (pObj->GetType()) { case eType1: m_pEntity1->Process(pObj); // may throw break; case eType2: g.arm(); m_pEntity2->Process(pObj); // may throw break; case eType3: g.arm(); m_pEntity3->Process(pObj); // may throw break; }; } Another example. Assume you have to operate with some non-trivial object. Something like that: void foo(CObject const& obj) { scope_guard g = make_guard(&PostActions, guard::disarmed); obj.foo1(); if (obj.is_ok()) { obj.foo2(param); if (obj.foo3(param)) do_smth(); else g.arm(); obj.foo4(); } do_smth_more(); } Both examples are very simplified but I hope they show the picture.

Andrey Semashev wrote:
Peter Dimov wrote:
Andrey Semashev wrote:
So, there was a really interesting and hot discussion about namings. Many opinions were expressed and I'd like to make some roundup.
I still think that the question "should X be included at all" is slightly more fundamental than "should X be named rearm, protect, or on". But this may be just me.
I'm sorry I didn't answer directly to you, but I wrote this in one of the descussion threads:
The more common use case is to create initially disabled guard and then, depending on some condition, activate it. I've had the need of such functionality several times.
I've tried to construct imaginary use cases that illustrate this, but in my experience, it is usually not possible to create the guard before acquiring the resource, because the guard needs to store the acquired resource. Something like FILE * f = fopen( ... ); if( f == 0 ) throw ...; scoped_guard file_closer = make_guard( fclose, f ); Even if the fopen is conditional, I can't create the guard and 'arm' it later, unless 'arm' takes parameters. Your examples don't carry enough context for me to be able to understand them. I'm pretty sure I can refactor every 'arm'ing example into one that doesn't need 'arm', but the interesting question is whether this refactoring would improve the code. Without some real examples, I can't answer this for myself.

The more common use case is to create initially disabled guard and then, depending on some condition, activate it. I've had the need of such functionality several times.
I've tried to construct imaginary use cases that illustrate this, but in my experience, it is usually not possible to create the guard before acquiring the resource, because the guard needs to store the acquired resource.
Something like
FILE * f = fopen( ... );
if( f == 0 ) throw ...;
scoped_guard file_closer = make_guard( fclose, f );
Even if the fopen is conditional, I can't create the guard and 'arm' it later, unless 'arm' takes parameters.
In this (or similar) case I might rather make a tiny wrapper around FILE* instead of guard. But that depends on the context and other factors. In this particular case "arm" would be useless.
Your examples don't carry enough context for me to be able to understand them. I'm pretty sure I can refactor every 'arm'ing example into one that doesn't need 'arm', but the interesting question is whether this refactoring would improve the code. Without some real examples, I can't answer this for myself.
I cannot show the real code since it's commercial. Though I can tell you that this code wouldn't become better if I tried to avoid the scope guard. Note that the place of creation (and therefore of destruction) in these examples (especially in the second one) is important and the guard cannot be created in place where it should be armed. So either create and arm guard separatedly, or try to avoid it at all. The latter makes the code worse. In my experience the use of this feature was rather specific but it was very useful though. And I don't see any reason why it shouldn't be included in the implementation. I can try to make up a more generic example but I need more time.

Andrey Semashev wrote:
FILE * f = fopen( ... );
if( f == 0 ) throw ...;
scoped_guard file_closer = make_guard( fclose, f );
In this (or similar) case I might rather make a tiny wrapper around FILE* instead of guard.
Interesting... when Andrei Alexandrescu and Petru Marginean introduced ScopeGuard, this was one of their primary motivating examples, and my initial reaction was that, indeed, biting the bullet and writing a separate File class might be a better option. Eliminating resource management as a motivation leaves me wondering what are the primary uses for scope[d]_guard that you have in mind?

"Peter Dimov" wrote:
Eliminating resource management as a motivation leaves me wondering what are the primary uses for scope[d]_guard that you have in mind?
There's one zillion of legacy APIs. People don't employ strict OO techniques all the time. The currect scope_guard has very poweful group-undo variant that could used to implement transation-like functionality. The arm() feature costs almost nothing, is quite natural and may came handy depending on design. /Pavel

"Pavel Vozenilek" <pavel_vozenilek@hotmail.com> writes:
Eliminating resource management as a motivation leaves me wondering what are the primary uses for scope[d]_guard that you have in mind?
There's one zillion of legacy APIs.
People don't employ strict OO techniques all the time.
The currect scope_guard has very poweful group-undo variant that could used to implement transation-like functionality.
The arm() feature costs almost nothing, is quite natural and may came handy depending on design.
Don't underestimate the cost of adding features for which there is no use case. It is high. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
"Pavel Vozenilek" <pavel_vozenilek@hotmail.com> writes:
The arm() feature costs almost nothing, is quite natural and may came handy depending on design.
Don't underestimate the cost of adding features for which there is no use case. It is high.
Since it is already implemented and takes no more than three lines of code I don't see how it may cost much. Besides, as I mentioned before, I had cases when it came useful. Maybe specific cases, but the fact is they were.

Peter Dimov wrote:
Andrey Semashev wrote:
FILE * f = fopen( ... );
if( f == 0 ) throw ...;
scoped_guard file_closer = make_guard( fclose, f );
In this (or similar) case I might rather make a tiny wrapper around FILE* instead of guard.
Interesting... when Andrei Alexandrescu and Petru Marginean introduced ScopeGuard, this was one of their primary motivating examples, and my initial reaction was that, indeed, biting the bullet and writing a separate File class might be a better option.
Eliminating resource management as a motivation leaves me wondering what are the primary uses for scope[d]_guard that you have in mind?
First, I didn't say the resource management area is not for scope guard. I just said that in this case it is questionable weither to use scope guard or making a tiny wrapper. And agreed that in this guard use case the "arm" method would be useless. Nothing more. Second, in addition to Pavel's note, there also is a lot of use cases of scope guard class which cannot be put to resouce management or transactions category. One of them, for example, is implementing post-processing queues which may help when you have complicated interactions between different objects that causes some of these objects get to an unexpected state. You may want to have such queue to perform the postponed actions after the call-stack is unrolled. The another use case is ensuring some action will be made regardless of the result of some part of program (the resource management comes as sub-category of this use case). By the way, the "arm" method is mostly used in the latter field. PS: Why scoped_guard? The object watches for the scope end to alarm, IOW he guards the scope. So scope_guard looks more applicable.

While I served in an English-speaking military organization, placing someone on active guard duty was to "post" them and removing them from active guard duty was to "relieve" them. Now, if "dismiss" is the preferred term for deactivating a guard, perhaps "summon" would be its more appropriate opposite? Andrey Semashev wrote:
- guard/dismiss. On the on hand, the commonly used "dismiss" should look familiar. On the other, its meaning is too strong in regard of the function semantic. The "guard" may be used as well but the word is already frequently used. Besides, the guard's status enum values' names propably won't corellate with these words (I just don't see the active status name with root "guard" - guard::guarding? :( ).

Jason Kankiewicz wrote:
While I served in an English-speaking military organization, placing someone on active guard duty was to "post" them and removing them from active guard duty was to "relieve" them.
Now, if "dismiss" is the preferred term for deactivating a guard, perhaps "summon" would be its more appropriate opposite?
Yes, the "summon" was one of the versions discussed. But it won't be good-looking in users code. See the discussion in the main thread "[scope_guard] New revision available + naming consideration".
Andrey Semashev wrote:
- guard/dismiss. On the on hand, the commonly used "dismiss" should look familiar. On the other, its meaning is too strong in regard of the function semantic. The "guard" may be used as well but the word is already frequently used. Besides, the guard's status enum values' names propably won't corellate with these words (I just don't see the active status name with root "guard" - guard::guarding? :( ).
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (5)
-
Andrey Semashev
-
David Abrahams
-
Jason Kankiewicz
-
Pavel Vozenilek
-
Peter Dimov