Re: [boost] Exception lib?

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Emil Dotchevski
Not to mention that the client can and will do it wrong.
I don't want to make a huge deal out of this because ultimately I don't mind hiding the dynamic_cast in a function get_exception_info. But I am arguing that this abstraction is not necessary because the only implementation possible is through a dynamic_cast (at least I can't think of another possibility).
Well for some people the only way to fix a const correctness related error is to remove the const. I can imagine people doing all sorts of (wrong)casts. IMHO, I think the api should constrain that freedom seeing as there *is* only one right way to do it! Sohail

Sohail Somani wrote:
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Emil Dotchevski
Not to mention that the client can and will do it wrong.
I don't want to make a huge deal out of this because ultimately I don't mind hiding the dynamic_cast in a function get_exception_info. But I am arguing that this abstraction is not necessary because the only implementation possible is through a dynamic_cast (at least I can't think of another possibility).
Well for some people the only way to fix a const correctness related error is to remove the const. I can imagine people doing all sorts of (wrong)casts. IMHO, I think the api should constrain that freedom seeing as there *is* only one right way to do it!
Please let's keep this to the point. There are no const_casts in the proposed Boost Exception library. If you think that the dynamic_cast can be avoided, I'm very much interested to hear how. If you think the need for dynamic_cast is a result of poor library design, I'm very much interested to hear about any improvement ideas. --Emil

On 7/6/06, Emil Dotchevski <emildotchevski@hotmail.com> wrote:
Please let's keep this to the point. There are no const_casts in the proposed Boost Exception library. If you think that the dynamic_cast can be avoided, I'm very much interested to hear how. If you think the need for dynamic_cast is a result of poor library design, I'm very much interested to hear about any improvement ideas.
Right now, I still haven't thought of a way to use some other facility aside from dynamic_cast<> but my point is more for abstraction and readability on the client code. The added abstraction will also allow you (and whoever will think of a way for bypassing the use of dynamic_cast) to change the implementation without having to worry about client code breaking. I'll probably do some of my own tests to figure out a way of possibly implementing the intended behavior without resorting to using a dynamic_cast<>. But for now, my concern remains to be the API by which the exception lib will be used/presented. It will also make the documentation much more readable and more informative IMO (and easier on the eyes) by removing the dynamic_cast<> and putting it in a macro/template abstraction. If the documentation didn't ever mention the use of dynamic_cast<>, then the users wouldn't even try attempting a dynamic_cast<> by themselves (unless they actually want to read the abstraction layer providing the functionality, which is a very rare case) -- and I for one wouldn't make too much a fuss about it. HTH -- Dean Michael C. Berris C/C++ Software Architect Orange and Bronze Software Labs http://3w-agility.blogspot.com/ http://cplusplus-soup.blogspot.com/ Mobile: +639287291459 Email: dean [at] orangeandbronze [dot] com

Dean Michael Berris wrote:
On 7/6/06, Emil Dotchevski <emildotchevski@hotmail.com> wrote:
Please let's keep this to the point. There are no const_casts in the proposed Boost Exception library. If you think that the dynamic_cast can be avoided, I'm very much interested to hear how. If you think the need for dynamic_cast is a result of poor library design, I'm very much interested to hear about any improvement ideas.
Right now, I still haven't thought of a way to use some other facility aside from dynamic_cast<> but my point is more for abstraction and readability on the client code. The added abstraction will also allow you (and whoever will think of a way for bypassing the use of dynamic_cast) to change the implementation without having to worry about client code breaking.
I'll probably do some of my own tests to figure out a way of possibly implementing the intended behavior without resorting to using a dynamic_cast<>. But for now, my concern remains to be the API by which the exception lib will be used/presented.
It will also make the documentation much more readable and more informative IMO (and easier on the eyes) by removing the dynamic_cast<> and putting it in a macro/template abstraction. If the documentation didn't ever mention the use of dynamic_cast<>, then the users wouldn't even try attempting a dynamic_cast<> by themselves (unless they actually want to read the abstraction layer providing the functionality, which is a very rare case) -- and I for one wouldn't make too much a fuss about it.
One thing is clear, get_exception_info wouldn't make much of a difference, and it would save me from having to explain why a dynamic_cast is alright here, so fine, I'll add get_exception_info. :) --Emil

On 7/5/06, Emil Dotchevski <emildotchevski@hotmail.com> wrote:
[snipped]
One thing is clear, get_exception_info wouldn't make much of a difference, and it would save me from having to explain why a dynamic_cast is alright here, so fine, I'll add get_exception_info. :)
I believe that get_exception_info makes a great difference! Obligating your users to use dynamic_cast you're making dynamic_cast being part of the interface of your library. Which makes no sense, dynamic_casts should be an implementation detail. And implementation details shouldnt be exposed by the interface.
--Emil
regards and looking forward for your library, -- Felipe Magno de Almeida

Felipe Magno de Almeida wrote:
I believe that get_exception_info makes a great difference! Obligating your users to use dynamic_cast you're making dynamic_cast being part of the interface of your library. Which makes no sense, dynamic_casts should be an implementation detail. And implementation details shouldnt be exposed by the interface.
I agree with you in principle, but I believe this case is an exception to that principle. For the exception library to work, the object thrown by throw failed<T>() must derive from T and from exception_info. If it was some other library, there are other implementations possible: maybe to make exception_info a member, or whatever. But because the whole point is to be able to catch(exception_info &), and to catch(T&), the exception type must derive from both. Therefore users know that dynamic_cast will work, with or without get_exception_info. People use interfaces to allow for different implementation strategies. But the only implementation possible for get_exception_info is to use dynamic_cast! Therefore, to me anyway, get_exception_info's purpose is to hide the dynamic_cast so I don't get emails like "why do you have a dynamic_cast as part of your interface". It's not part of the interface, it's part of C++. It does exactly what you need when you catch(T&) and want to see if you can get an exception_info *. --Emil

On 7/9/06, Emil Dotchevski <emildotchevski@hotmail.com> wrote:
[snipped]
I agree with you in principle, but I believe this case is an exception to that principle.
For the exception library to work, the object thrown by throw failed<T>() must derive from T and from exception_info. If it was some other library, there are other implementations possible: maybe to make exception_info a member, or whatever. But because the whole point is to be able to catch(exception_info &), and to catch(T&), the exception type must derive from both.
Therefore users know that dynamic_cast will work, with or without get_exception_info.
People use interfaces to allow for different implementation strategies. But the only implementation possible for get_exception_info is to use dynamic_cast!
That is not the only reason. The implementation is just a detail from a user point of view, things that expose that implementation become a distraction to the user. Which, usually, dont care about how it is done, as long it works as expected.
Therefore, to me anyway, get_exception_info's purpose is to hide the dynamic_cast so I don't get emails like "why do you have a dynamic_cast as part of your interface". It's not part of the interface, it's part of C++. It does exactly what you need when you catch(T&) and want to see if you can get an exception_info *.
If a user has to use dynamic_cast to be able to use the library then it is part of the interface too, IMO. And asking why seems to me like a very reasonable question. Now, using dynamic_cast to implement the library is not a problem, since it is not of my concern as a user. As an example of good implementation hiding, boost::function uses void* all over the place, albeit its interface is as clean and straightforward as it can be. Even if void* is or isnt the only implementation possible. I, as a user, do not have any interest in glimpsing over any void* to be able to use boost::function.
--Emil
regards, -- Felipe Magno de Almeida

Felipe Magno de Almeida wrote:
People use interfaces to allow for different implementation strategies. But the only implementation possible for get_exception_info is to use dynamic_cast!
That is not the only reason. The implementation is just a detail from a user point of view, things that expose that implementation become a distraction to the user.
Are you saying that the user knows that the object returned by failed<T> derives from both T and exception info, yet is distracted by the fact that dynamic_cast can be used to go from T * to exception_info *? I'm not arguing that to have a function get_exception_info is unreasonable -- someone may have their reasons to define it. But IMO this is beyond the scope of the exception library.
Therefore, to me anyway, get_exception_info's purpose is to hide the dynamic_cast so I don't get emails like "why do you have a dynamic_cast as part of your interface". It's not part of the interface, it's part of C++. It does exactly what you need when you catch(T&) and want to see if you can get an exception_info *.
If a user has to use dynamic_cast to be able to use the library then it is part of the interface too, IMO.
The users also have to use "throw" to use the library, and indeed it makes sense to hide it in a function (or a macro) because someone might want to compile with exception handling disabled. Or to not throw if it's Friday the 13th. But this is beyond the scope of the exception library.
And asking why seems to me like a very reasonable question.
I'm not arguing that "why haven't you hidden the dynamic_cast in a function" is unreasonable question.
Now, using dynamic_cast to implement the library is not a problem, since it is not of my concern as a user.
Except that it is also reasonable for someone, after reading the documentation, to be puzzled why was it necessary to write get_exception_info when dynamic_cast is the only way it can be implemented.
As an example of good implementation hiding, boost::function uses void* all over the place, albeit its interface is as clean and straightforward as it can be. Even if void* is or isnt the only implementation possible.
There are many other examples that (correctly) hide implementation details behind an interface. There are many cases about which I'd agree that hiding a dynamic_cast behind an interface is necessary. Regards, Emil

Emil Dotchevski wrote:
I'm not arguing that to have a function get_exception_info is unreasonable -- someone may have their reasons to define it. But IMO this is beyond the scope of the exception library.
I think that it might be a good reason to extend the scope. B.

On 7/9/06, Emil Dotchevski <emildotchevski@hotmail.com> wrote:
Felipe Magno de Almeida wrote:
People use interfaces to allow for different implementation strategies. But the only implementation possible for get_exception_info is to use dynamic_cast!
That is not the only reason. The implementation is just a detail from a user point of view, things that expose that implementation become a distraction to the user.
Are you saying that the user knows that the object returned by failed<T> derives from both T and exception info, yet is distracted by the fact that dynamic_cast can be used to go from T * to exception_info *?
What I'm trying to say, but seems to be failing miserably, is that failed<T> deriving from T and exception_info is too an implementation detail. All the user should need to know is that throwing failed<T> he is able to catch T& and get exception_info from this exception, where he can add and retrieve data about the exception occurred. Consequently, dynamic_cast is also an implementation detail which only distracts the user from its goal:
I'm not arguing that to have a function get_exception_info is unreasonable -- someone may have their reasons to define it. But IMO this is beyond the scope of the exception library.
No, I didnt mean that you were saying that. In fact, you already agreed to create it. But what I'm saying is that such a function is not only in the scope of the library but is also essential for a clean interface. Where implementation isnt exposed on the interface, being or not the only implementation possible is of no interest to the user. [snipped]
If a user has to use dynamic_cast to be able to use the library then it is part of the interface too, IMO.
The users also have to use "throw" to use the library, and indeed it makes sense to hide it in a function (or a macro) because someone might want to compile with exception handling disabled. Or to not throw if it's Friday the 13th. But this is beyond the scope of the exception library.
The difference is that it is supposed to be a 'exception library', and not a 'create a temporary that derives from T and something else library', for which the dynamic_cast would be very sensitive. The temporary deriving from whatever it derives is just a detail and should be hided from users. [snipped]
Now, using dynamic_cast to implement the library is not a problem, since it is not of my concern as a user.
Except that it is also reasonable for someone, after reading the documentation, to be puzzled why was it necessary to write get_exception_info when dynamic_cast is the only way it can be implemented.
I cant see why a user would ask such a thing. First of all he shouldnt even know, unless he really really want to know, that dynamic_cast is able to return an exception_info*.
As an example of good implementation hiding, boost::function uses void* all over the place, albeit its interface is as clean and straightforward as it can be. Even if void* is or isnt the only implementation possible.
There are many other examples that (correctly) hide implementation details behind an interface. There are many cases about which I'd agree that hiding a dynamic_cast behind an interface is necessary.
Looks like none of us is going to change its mind, so I believe we should just let the discussion, if get_exception_info is or isnt necessary, die.
Regards, Emil
Best regards, -- Felipe Magno de Almeida

Felipe Magno de Almeida wrote:
What I'm trying to say, but seems to be failing miserably, is that failed<T> deriving from T and exception_info is too an implementation detail.
No, it's not. It's a key promise of the library that both T& and exception_info& can be caught, i.e. that the object returned by failed<>() derives from both. It's part of the interface. Sebastian Redl
participants (6)
-
Bronek Kozicki
-
Dean Michael Berris
-
Emil Dotchevski
-
Felipe Magno de Almeida
-
Sebastian Redl
-
Sohail Somani