Improving Pharo's Exception Hierarchy

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
54 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Dale Henrichs
Nicolas,

Well put:)

Dale

On 04/13/2011 02:20 PM, Nicolas Cellier wrote:

> What's wrong is simple to explain: Your image is a namespace. The more
> names you have, the more difficult it is to apprehend, understand and
> reuse.
>
> Wait, wait, wait, you might say, whether I use Symbols or Class names,
> there are always the same number of names at the end.
>
> Yes, but what makes the big difference is the IDE. What we see thru
> this IDE is either:
> - a view by package or protocol
> - a hierarchical view.
>
> How to find if a specific Exception exists, what it's name is ?
> By now, I find package names misleading, because not very uniform.
> Even if uniformized, it's not always obvious where to search for.
> Plus, there are a lot of packages.
> The hierarchical view would be more natural, but is to my taste
> unusable above 30 items. I find current Exception hierarchy
> unfriendly.
> So the idea to use a double classification, a quite generic exception
> name like FileError and a specialization "code" does make sense.
>
> You must understand this, when our neurons were younger, we learnt
> Smalltalk with a ~300 classes image. What a great pleasure to be able
> to embrace the whole system !
> Now our older neurons must remember about 8x more...
> So we appreciate the inflation with a different scale.
>
> Nicolas
>
> 2011/4/13 Toon Verwaest<[hidden email]>:
>> I find the "managing the exception hierarchy" a bit strange... Do you really
>> have to manage anything more than just normal classes? Every exception is
>> related to a specific part of your code, just like other classes. What's
>> wrong with creating hundreds of small classes wherever it's necessary? You
>> might save a tiny bit of memory by using error codes or symbols, but I don't
>> really see much more of a gain there, while you do gain from proper objects.
>>
>> Being clear and modeling properly generally pays off in the long run. And
>> the bit of runtime memory you save isn't really worth your while...
>>
>> Or am I missing something else? I didn't really follow the whole
>> conversation in-depth.
>>
>> cheers,
>> Toon
>>
>> On 04/13/2011 09:54 PM, Dale Henrichs wrote:
>>>
>>> Camillo,
>>>
>>> Hey, I _am_ old, but not _that_ old:) ... There are a couple of things
>>> that were invented in the Stone Age that have survived to today, so old
>>> ideas are not immediately bad, because they are old:)
>>>
>>> It feels like you are creating classes that are not much more than symbols
>>> ...
>>>
>>> I am not one to shy away from using classes when they are called for, but
>>> I am just making a practicality point ... we don't have a unique class for
>>> each character in the alphabet, but we could....we could have a unique class
>>> for every possible error condition or not ...
>>>
>>> I think it is simply a practical answer...
>>>
>>> I do maintain that you _should_ use some sort of test along the lines of:
>>> "Will anyone ever need to write a handler for the exception?" in your
>>> criteria for deciding when to create a class and when to use something like
>>> a "reason code" to disambiguate the signalling site...
>>>
>>> Dale
>>>
>>> On 04/13/2011 12:32 PM, Camillo Bruni wrote:
>>>>
>>>> Perfect, I ll be there to bang heads ;).
>>>>
>>>> So without "Exception" pre- or suffix seems to be nice. However I
>>>> don't see the need of using symbols over real classes. This feels
>>>> indeed like going to stone age of error handling, thats what you have
>>>> polymorphism and ExceptionSets for.
>>>>
>>>> Anyway, the main idea is to make single exceptions recognizable and
>>>> not just use one single, basically meaningless, exception type.
>>>>
>>>> best regards, Camillo Bruni
>>>>
>>>>
>>>> On 2011-04-13, at 21:22, Sven Van Caekenberghe wrote:
>>>>
>>>>> Thanks a lot everybody for the reactions, this could become a nice
>>>>> discussion next Friday. All points raised are valid, I would like
>>>>> simple names and a compact multipurpose hierarchy too.
>>>>>
>>>>> On 13 Apr 2011, at 19:39, Dale Henrichs wrote:
>>>>>
>>>>>> Some thoughts from an old man (started programming before
>>>>>> exceptions of any kind were available:) ...
>>>>>>
>>>>>> In the old days, error numbers had a place in the universe ...
>>>>>> error numbers of a certain range indicated specific errors and
>>>>>> the "error handlers" could check for a range or a specific error
>>>>>> ...
>>>>>>
>>>>>> Today I think there is still a place for the notion of "error
>>>>>> numbers".
>>>>>>
>>>>>> In Smalltalk I would use Symbols instead of numbers, but the idea
>>>>>> would be to use a concrete exception class to identify broad
>>>>>> categories of error conditions (i.e., FileStreamError) and a
>>>>>> symbolic "reason code" to indicate the specific error (i.e.,
>>>>>> #fileDoesNotExist, #fileExists, #cannotDelete, etc.), that way an
>>>>>> error handler can be written for FileStreamError and then
>>>>>> specific action take with respect to which "reason code" is
>>>>>> involved, if such action is needed.
>>>>>>
>>>>>> The main advantage of using reasonCodes over using a "class per
>>>>>> error condition" is that you can reduce the size of the Exception
>>>>>> hierarchy to a manageable size (GemStone has hundreds of error
>>>>>> conditions, so we've resorted to using "reason codes" to manage
>>>>>> the size of the hierarchy).
>>>>>>
>>>>>> As Hernan hints, more often than not it is important to be very
>>>>>> specific about the error condition when signalling an error (a
>>>>>> unique error message per "per reason code" would be desirable),
>>>>>> but the there are very few places where the handler is going to
>>>>>> be that specific ...
>>>>>>
>>>>>> In other words, if it is likely that programmers in the course of
>>>>>> using an application will be writing specific error handlers to
>>>>>> distinguish between the KeyNotFound and ValueNotFound condition,
>>>>>> then classes should be created, otherwise, the NotFoundException
>>>>>> could be implemented with three reason codes: #keyNotFound,
>>>>>> #valueNotFound, and #elementNotFound and you'd get the best of
>>>>>> both worlds, explicit information at the signalling site and a
>>>>>> much smaller and more manageable Exception class hierarchy.
>>>>>>
>>>>>> Dale
>>>>>>
>>>>>> On 04/13/2011 10:15 AM, Hernan Wilkinson wrote:
>>>>>>>
>>>>>>> I think it is not a good idea to use the prefix Exception. We
>>>>>>> do not use the word "exception" in real life, so we should not
>>>>>>> do it on our systems. About the proposed hierarchy, the problem
>>>>>>> with having specific exceptions is that they are important for
>>>>>>> those who catch them, not for those who signal them. For
>>>>>>> example, besides the name, what is the difference between
>>>>>>> KeyNotFound or ValueNotFound? none. So, I think that the
>>>>>>> exception hierarchy should be grown from it uses, not created
>>>>>>> based on how or where they are signaled.
>>>>>>>
>>>>>>> my 2 cents :-)
>>>>>>>
>>>>>>> On Wed, Apr 13, 2011 at 1:55 PM, Miguel
>>>>>>> Cobá<[hidden email]<mailto:[hidden email]>>
>>>>>>> wrote:
>>>>>>>
>>>>>>> El mié, 13-04-2011 a las 14:52 +0200, Camillo Bruni escribió:
>>>>>>>
>>>>>>>> And as Mariano pointed out, there should be a convention on
>>>>>>>> the naming: I am still not sure about suffixing the exception
>>>>>>>> classes
>>>>>>>
>>>>>>> with
>>>>>>>>
>>>>>>>> "Exception", but I guess this is a good thing to do. Though
>>>>>>>> I
>>>>>>>
>>>>>>> must say
>>>>>>>>
>>>>>>>> that I omitted it so far ;) and just put the verb there, but
>>>>>>>> that can be easily changed.
>>>>>>>
>>>>>>> I would say no to suffixes. Analogous to announcements, they
>>>>>>> shouldn't have the suffix. The name should be descriptive
>>>>>>> enough and intention revealing that the suffix isn't needed in
>>>>>>> most cases. For example, I think that
>>>>>>>
>>>>>>> DividedByZero
>>>>>>>
>>>>>>> is better than
>>>>>>>
>>>>>>> DividedByZeroException
>>>>>>>
>>>>>>> and no information is lost with the sorter name. Instead,
>>>>>>> DivideByZero isn't clear enough to indicate that is a event
>>>>>>> that happened.
>>>>>>>
>>>>>>> What do you think?
>>>>>>>
>>>>>>> -- Miguel Cobá http://twitter.com/MiguelCobaMtz
>>>>>>> http://miguel.leugim.com.mx
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> -- *Hernán Wilkinson Agile Software Development, Teaching&
>>>>>>> Coaching Mobile: +54 - 911 - 4470 - 7207 email:
>>>>>>> [hidden email] site:
>>>>>>> http://www.10Pines.com<http://www.10pines.com/>*
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>>
>


Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Toon Verwaest-2
In reply to this post by Dale Henrichs
Is it such a problem if you duplicate a certain exception class? At the
moment you'll do the same anyway by not completely writing the exact
same symbol.

And if the problem is not finding classes anymore, maybe we need a
better way of organizing the exception classes away from the standard
classes so that they are as non-intrusive as symbols, but convey more
information?

self error: #keyNotFound
does not really give much information; and isn't much more difficult to
write than:
KeyNotFoundException new in: self; key: key; signal

although the second one gives you all the contextual information that
the first one misses.

What I mean mostly: what about trying to figure out why you want to
avoid decent exception classes and tackling that problem?
Maybe we don't want classes but exception objects that can pool data
together? Maybe a very silly idea: what about just exception "classes"
that have dictionaries to store enough information?

cheers,
Toon

On 04/13/2011 11:31 PM, Dale Henrichs wrote:

> By managing the class hierarchy:
>
>   Imagine trying to find meaningful exception classes in a class
>   hierarchy of 10,000 classes with significant nesting vs finding a
>   meaningful class in a hierarchy of 10 classes ... at what point does
>   the hierarchy get out of hand?
>
>
> I think GemStone had 600 some unique errors and that was pared down to
> <30 Exception classes with reason codes...
>
> It's a matter of practicality...I would think that somewhere around
> 100 classes the hierarchy starts to become very tedious to understand
> even for those trying to find the right place to insert there brand
> spanking new exception class.
>
> 99% of exception handlers will _use_ Error_ anyway, so the exception
> hierarchy will be largely ignored by most folks, especially if it is
> large an unwieldly.
>
> 100 small classes that serve a real purpose and have explicit
> exception handlers written using every one of them, well then by god!
> 100 classes are absolutely called for.
>
> To me this is different than 100 places where I signal an exception
> ... do really need a different exception class for each of the 100
> signalling sites? What if there are no handlers written for any of
> them? Like I said, if there are legitimate need to handle an
> exception, then there is a legitimate need to create an exception
> class, but if I have 5 different error conditions, but I will have a
> single exception handler for all 5 conditions, _should_ I create 5
> classes or 1 class with some state to disambiguate?
>
> If your answer is "It depends...", then you will understand what I am
> saying:)
>
> Dale
>
> On 04/13/2011 02:01 PM, Toon Verwaest wrote:
>> I find the "managing the exception hierarchy" a bit strange... Do you
>> really have to manage anything more than just normal classes? Every
>> exception is related to a specific part of your code, just like other
>> classes. What's wrong with creating hundreds of small classes wherever
>> it's necessary? You might save a tiny bit of memory by using error codes
>> or symbols, but I don't really see much more of a gain there, while you
>> do gain from proper objects.
>>
>> Being clear and modeling properly generally pays off in the long run.
>> And the bit of runtime memory you save isn't really worth your while...
>>
>> Or am I missing something else? I didn't really follow the whole
>> conversation in-depth.
>>
>> cheers,
>> Toon
>>
>> On 04/13/2011 09:54 PM, Dale Henrichs wrote:
>>> Camillo,
>>>
>>> Hey, I _am_ old, but not _that_ old:) ... There are a couple of things
>>> that were invented in the Stone Age that have survived to today, so
>>> old ideas are not immediately bad, because they are old:)
>>>
>>> It feels like you are creating classes that are not much more than
>>> symbols ...
>>>
>>> I am not one to shy away from using classes when they are called for,
>>> but I am just making a practicality point ... we don't have a unique
>>> class for each character in the alphabet, but we could....we could
>>> have a unique class for every possible error condition or not ...
>>>
>>> I think it is simply a practical answer...
>>>
>>> I do maintain that you _should_ use some sort of test along the lines
>>> of: "Will anyone ever need to write a handler for the exception?" in
>>> your criteria for deciding when to create a class and when to use
>>> something like a "reason code" to disambiguate the signalling site...
>>>
>>> Dale
>>>
>>> On 04/13/2011 12:32 PM, Camillo Bruni wrote:
>>>> Perfect, I ll be there to bang heads ;).
>>>>
>>>> So without "Exception" pre- or suffix seems to be nice. However I
>>>> don't see the need of using symbols over real classes. This feels
>>>> indeed like going to stone age of error handling, thats what you have
>>>> polymorphism and ExceptionSets for.
>>>>
>>>> Anyway, the main idea is to make single exceptions recognizable and
>>>> not just use one single, basically meaningless, exception type.
>>>>
>>>> best regards, Camillo Bruni
>>>>
>>>>
>>>> On 2011-04-13, at 21:22, Sven Van Caekenberghe wrote:
>>>>
>>>>> Thanks a lot everybody for the reactions, this could become a nice
>>>>> discussion next Friday. All points raised are valid, I would like
>>>>> simple names and a compact multipurpose hierarchy too.
>>>>>
>>>>> On 13 Apr 2011, at 19:39, Dale Henrichs wrote:
>>>>>
>>>>>> Some thoughts from an old man (started programming before
>>>>>> exceptions of any kind were available:) ...
>>>>>>
>>>>>> In the old days, error numbers had a place in the universe ...
>>>>>> error numbers of a certain range indicated specific errors and
>>>>>> the "error handlers" could check for a range or a specific error
>>>>>> ...
>>>>>>
>>>>>> Today I think there is still a place for the notion of "error
>>>>>> numbers".
>>>>>>
>>>>>> In Smalltalk I would use Symbols instead of numbers, but the idea
>>>>>> would be to use a concrete exception class to identify broad
>>>>>> categories of error conditions (i.e., FileStreamError) and a
>>>>>> symbolic "reason code" to indicate the specific error (i.e.,
>>>>>> #fileDoesNotExist, #fileExists, #cannotDelete, etc.), that way an
>>>>>> error handler can be written for FileStreamError and then
>>>>>> specific action take with respect to which "reason code" is
>>>>>> involved, if such action is needed.
>>>>>>
>>>>>> The main advantage of using reasonCodes over using a "class per
>>>>>> error condition" is that you can reduce the size of the Exception
>>>>>> hierarchy to a manageable size (GemStone has hundreds of error
>>>>>> conditions, so we've resorted to using "reason codes" to manage
>>>>>> the size of the hierarchy).
>>>>>>
>>>>>> As Hernan hints, more often than not it is important to be very
>>>>>> specific about the error condition when signalling an error (a
>>>>>> unique error message per "per reason code" would be desirable),
>>>>>> but the there are very few places where the handler is going to
>>>>>> be that specific ...
>>>>>>
>>>>>> In other words, if it is likely that programmers in the course of
>>>>>> using an application will be writing specific error handlers to
>>>>>> distinguish between the KeyNotFound and ValueNotFound condition,
>>>>>> then classes should be created, otherwise, the NotFoundException
>>>>>> could be implemented with three reason codes: #keyNotFound,
>>>>>> #valueNotFound, and #elementNotFound and you'd get the best of
>>>>>> both worlds, explicit information at the signalling site and a
>>>>>> much smaller and more manageable Exception class hierarchy.
>>>>>>
>>>>>> Dale
>>>>>>
>>>>>> On 04/13/2011 10:15 AM, Hernan Wilkinson wrote:
>>>>>>> I think it is not a good idea to use the prefix Exception. We
>>>>>>> do not use the word "exception" in real life, so we should not
>>>>>>> do it on our systems. About the proposed hierarchy, the problem
>>>>>>> with having specific exceptions is that they are important for
>>>>>>> those who catch them, not for those who signal them. For
>>>>>>> example, besides the name, what is the difference between
>>>>>>> KeyNotFound or ValueNotFound? none. So, I think that the
>>>>>>> exception hierarchy should be grown from it uses, not created
>>>>>>> based on how or where they are signaled.
>>>>>>>
>>>>>>> my 2 cents :-)
>>>>>>>
>>>>>>> On Wed, Apr 13, 2011 at 1:55 PM, Miguel
>>>>>>> Cobá<[hidden email]<mailto:[hidden email]>>
>>>>>>> wrote:
>>>>>>>
>>>>>>> El mié, 13-04-2011 a las 14:52 +0200, Camillo Bruni escribió:
>>>>>>>
>>>>>>>> And as Mariano pointed out, there should be a convention on
>>>>>>>> the naming: I am still not sure about suffixing the exception
>>>>>>>> classes
>>>>>>> with
>>>>>>>> "Exception", but I guess this is a good thing to do. Though
>>>>>>>> I
>>>>>>> must say
>>>>>>>> that I omitted it so far ;) and just put the verb there, but
>>>>>>>> that can be easily changed.
>>>>>>>
>>>>>>> I would say no to suffixes. Analogous to announcements, they
>>>>>>> shouldn't have the suffix. The name should be descriptive
>>>>>>> enough and intention revealing that the suffix isn't needed in
>>>>>>> most cases. For example, I think that
>>>>>>>
>>>>>>> DividedByZero
>>>>>>>
>>>>>>> is better than
>>>>>>>
>>>>>>> DividedByZeroException
>>>>>>>
>>>>>>> and no information is lost with the sorter name. Instead,
>>>>>>> DivideByZero isn't clear enough to indicate that is a event
>>>>>>> that happened.
>>>>>>>
>>>>>>> What do you think?
>>>>>>>
>>>>>>> -- Miguel Cobá http://twitter.com/MiguelCobaMtz
>>>>>>> http://miguel.leugim.com.mx
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> -- *Hernán Wilkinson Agile Software Development, Teaching&
>>>>>>> Coaching Mobile: +54 - 911 - 4470 - 7207 email:
>>>>>>> [hidden email] site:
>>>>>>> http://www.10Pines.com<http://www.10pines.com/>*
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>


Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Nicolas Cellier
Reusing is important because it means reducing the number of concepts
and reducing the complexity.
Once we fail to manage this complexity, the image grows exponentially:
two times more classes means half chance to find matching information,
and twice to reinvent.

But of course, that does not mean Classes must not be used. Create
KeyNotFound if you need it, and let it carry precious information.

Nicolas

2011/4/13 Toon Verwaest <[hidden email]>:

> Is it such a problem if you duplicate a certain exception class? At the
> moment you'll do the same anyway by not completely writing the exact same
> symbol.
>
> And if the problem is not finding classes anymore, maybe we need a better
> way of organizing the exception classes away from the standard classes so
> that they are as non-intrusive as symbols, but convey more information?
>
> self error: #keyNotFound
> does not really give much information; and isn't much more difficult to
> write than:
> KeyNotFoundException new in: self; key: key; signal
>
> although the second one gives you all the contextual information that the
> first one misses.
>
> What I mean mostly: what about trying to figure out why you want to avoid
> decent exception classes and tackling that problem?
> Maybe we don't want classes but exception objects that can pool data
> together? Maybe a very silly idea: what about just exception "classes" that
> have dictionaries to store enough information?
>
> cheers,
> Toon
>
> On 04/13/2011 11:31 PM, Dale Henrichs wrote:
>>
>> By managing the class hierarchy:
>>
>>  Imagine trying to find meaningful exception classes in a class
>>  hierarchy of 10,000 classes with significant nesting vs finding a
>>  meaningful class in a hierarchy of 10 classes ... at what point does
>>  the hierarchy get out of hand?
>>
>>
>> I think GemStone had 600 some unique errors and that was pared down to <30
>> Exception classes with reason codes...
>>
>> It's a matter of practicality...I would think that somewhere around 100
>> classes the hierarchy starts to become very tedious to understand even for
>> those trying to find the right place to insert there brand spanking new
>> exception class.
>>
>> 99% of exception handlers will _use_ Error_ anyway, so the exception
>> hierarchy will be largely ignored by most folks, especially if it is large
>> an unwieldly.
>>
>> 100 small classes that serve a real purpose and have explicit exception
>> handlers written using every one of them, well then by god! 100 classes are
>> absolutely called for.
>>
>> To me this is different than 100 places where I signal an exception ... do
>> really need a different exception class for each of the 100 signalling
>> sites? What if there are no handlers written for any of them? Like I said,
>> if there are legitimate need to handle an exception, then there is a
>> legitimate need to create an exception class, but if I have 5 different
>> error conditions, but I will have a single exception handler for all 5
>> conditions, _should_ I create 5 classes or 1 class with some state to
>> disambiguate?
>>
>> If your answer is "It depends...", then you will understand what I am
>> saying:)
>>
>> Dale
>>
>> On 04/13/2011 02:01 PM, Toon Verwaest wrote:
>>>
>>> I find the "managing the exception hierarchy" a bit strange... Do you
>>> really have to manage anything more than just normal classes? Every
>>> exception is related to a specific part of your code, just like other
>>> classes. What's wrong with creating hundreds of small classes wherever
>>> it's necessary? You might save a tiny bit of memory by using error codes
>>> or symbols, but I don't really see much more of a gain there, while you
>>> do gain from proper objects.
>>>
>>> Being clear and modeling properly generally pays off in the long run.
>>> And the bit of runtime memory you save isn't really worth your while...
>>>
>>> Or am I missing something else? I didn't really follow the whole
>>> conversation in-depth.
>>>
>>> cheers,
>>> Toon
>>>
>>> On 04/13/2011 09:54 PM, Dale Henrichs wrote:
>>>>
>>>> Camillo,
>>>>
>>>> Hey, I _am_ old, but not _that_ old:) ... There are a couple of things
>>>> that were invented in the Stone Age that have survived to today, so
>>>> old ideas are not immediately bad, because they are old:)
>>>>
>>>> It feels like you are creating classes that are not much more than
>>>> symbols ...
>>>>
>>>> I am not one to shy away from using classes when they are called for,
>>>> but I am just making a practicality point ... we don't have a unique
>>>> class for each character in the alphabet, but we could....we could
>>>> have a unique class for every possible error condition or not ...
>>>>
>>>> I think it is simply a practical answer...
>>>>
>>>> I do maintain that you _should_ use some sort of test along the lines
>>>> of: "Will anyone ever need to write a handler for the exception?" in
>>>> your criteria for deciding when to create a class and when to use
>>>> something like a "reason code" to disambiguate the signalling site...
>>>>
>>>> Dale
>>>>
>>>> On 04/13/2011 12:32 PM, Camillo Bruni wrote:
>>>>>
>>>>> Perfect, I ll be there to bang heads ;).
>>>>>
>>>>> So without "Exception" pre- or suffix seems to be nice. However I
>>>>> don't see the need of using symbols over real classes. This feels
>>>>> indeed like going to stone age of error handling, thats what you have
>>>>> polymorphism and ExceptionSets for.
>>>>>
>>>>> Anyway, the main idea is to make single exceptions recognizable and
>>>>> not just use one single, basically meaningless, exception type.
>>>>>
>>>>> best regards, Camillo Bruni
>>>>>
>>>>>
>>>>> On 2011-04-13, at 21:22, Sven Van Caekenberghe wrote:
>>>>>
>>>>>> Thanks a lot everybody for the reactions, this could become a nice
>>>>>> discussion next Friday. All points raised are valid, I would like
>>>>>> simple names and a compact multipurpose hierarchy too.
>>>>>>
>>>>>> On 13 Apr 2011, at 19:39, Dale Henrichs wrote:
>>>>>>
>>>>>>> Some thoughts from an old man (started programming before
>>>>>>> exceptions of any kind were available:) ...
>>>>>>>
>>>>>>> In the old days, error numbers had a place in the universe ...
>>>>>>> error numbers of a certain range indicated specific errors and
>>>>>>> the "error handlers" could check for a range or a specific error
>>>>>>> ...
>>>>>>>
>>>>>>> Today I think there is still a place for the notion of "error
>>>>>>> numbers".
>>>>>>>
>>>>>>> In Smalltalk I would use Symbols instead of numbers, but the idea
>>>>>>> would be to use a concrete exception class to identify broad
>>>>>>> categories of error conditions (i.e., FileStreamError) and a
>>>>>>> symbolic "reason code" to indicate the specific error (i.e.,
>>>>>>> #fileDoesNotExist, #fileExists, #cannotDelete, etc.), that way an
>>>>>>> error handler can be written for FileStreamError and then
>>>>>>> specific action take with respect to which "reason code" is
>>>>>>> involved, if such action is needed.
>>>>>>>
>>>>>>> The main advantage of using reasonCodes over using a "class per
>>>>>>> error condition" is that you can reduce the size of the Exception
>>>>>>> hierarchy to a manageable size (GemStone has hundreds of error
>>>>>>> conditions, so we've resorted to using "reason codes" to manage
>>>>>>> the size of the hierarchy).
>>>>>>>
>>>>>>> As Hernan hints, more often than not it is important to be very
>>>>>>> specific about the error condition when signalling an error (a
>>>>>>> unique error message per "per reason code" would be desirable),
>>>>>>> but the there are very few places where the handler is going to
>>>>>>> be that specific ...
>>>>>>>
>>>>>>> In other words, if it is likely that programmers in the course of
>>>>>>> using an application will be writing specific error handlers to
>>>>>>> distinguish between the KeyNotFound and ValueNotFound condition,
>>>>>>> then classes should be created, otherwise, the NotFoundException
>>>>>>> could be implemented with three reason codes: #keyNotFound,
>>>>>>> #valueNotFound, and #elementNotFound and you'd get the best of
>>>>>>> both worlds, explicit information at the signalling site and a
>>>>>>> much smaller and more manageable Exception class hierarchy.
>>>>>>>
>>>>>>> Dale
>>>>>>>
>>>>>>> On 04/13/2011 10:15 AM, Hernan Wilkinson wrote:
>>>>>>>>
>>>>>>>> I think it is not a good idea to use the prefix Exception. We
>>>>>>>> do not use the word "exception" in real life, so we should not
>>>>>>>> do it on our systems. About the proposed hierarchy, the problem
>>>>>>>> with having specific exceptions is that they are important for
>>>>>>>> those who catch them, not for those who signal them. For
>>>>>>>> example, besides the name, what is the difference between
>>>>>>>> KeyNotFound or ValueNotFound? none. So, I think that the
>>>>>>>> exception hierarchy should be grown from it uses, not created
>>>>>>>> based on how or where they are signaled.
>>>>>>>>
>>>>>>>> my 2 cents :-)
>>>>>>>>
>>>>>>>> On Wed, Apr 13, 2011 at 1:55 PM, Miguel
>>>>>>>> Cobá<[hidden email]<mailto:[hidden email]>>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>> El mié, 13-04-2011 a las 14:52 +0200, Camillo Bruni escribió:
>>>>>>>>
>>>>>>>>> And as Mariano pointed out, there should be a convention on
>>>>>>>>> the naming: I am still not sure about suffixing the exception
>>>>>>>>> classes
>>>>>>>>
>>>>>>>> with
>>>>>>>>>
>>>>>>>>> "Exception", but I guess this is a good thing to do. Though
>>>>>>>>> I
>>>>>>>>
>>>>>>>> must say
>>>>>>>>>
>>>>>>>>> that I omitted it so far ;) and just put the verb there, but
>>>>>>>>> that can be easily changed.
>>>>>>>>
>>>>>>>> I would say no to suffixes. Analogous to announcements, they
>>>>>>>> shouldn't have the suffix. The name should be descriptive
>>>>>>>> enough and intention revealing that the suffix isn't needed in
>>>>>>>> most cases. For example, I think that
>>>>>>>>
>>>>>>>> DividedByZero
>>>>>>>>
>>>>>>>> is better than
>>>>>>>>
>>>>>>>> DividedByZeroException
>>>>>>>>
>>>>>>>> and no information is lost with the sorter name. Instead,
>>>>>>>> DivideByZero isn't clear enough to indicate that is a event
>>>>>>>> that happened.
>>>>>>>>
>>>>>>>> What do you think?
>>>>>>>>
>>>>>>>> -- Miguel Cobá http://twitter.com/MiguelCobaMtz
>>>>>>>> http://miguel.leugim.com.mx
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> -- *Hernán Wilkinson Agile Software Development, Teaching&
>>>>>>>> Coaching Mobile: +54 - 911 - 4470 - 7207 email:
>>>>>>>> [hidden email] site:
>>>>>>>> http://www.10Pines.com<http://www.10pines.com/>*
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Dale Henrichs
In reply to this post by Toon Verwaest-2
On 04/13/2011 02:58 PM, Toon Verwaest wrote:
> Is it such a problem if you duplicate a certain exception class? At the
> moment you'll do the same anyway by not completely writing the exact
> same symbol.

It's a simple matter of namespaces and volume of names ... with a large
open ended namespace you are more likely to have a number of redundant
names with slight differences in spelling showing up in different spots
in the hierarchy...with a logically segmented namespace each segment
will have a manageable number of names and the risk of duplication is
reduced ... end of discussion ...

10,000 names vs 30 names ... I can easily recognize duplicates in a list
of 30 names ... not so easy in 10,000 ... that is all ...

to attempt to map every possible error condition onto a class will lead
you to 10,000 much quicker than using reasonCodes ... that is all ...

I don't hate classes, it is a _practical_ matter ... if _you_ would
rather manage 10,000 names then I will say that it isn't practical ...
I'm _not_ saying it is _wrong_, just not _practical_.

>
> And if the problem is not finding classes anymore, maybe we need a
> better way of organizing the exception classes away from the standard
> classes so that they are as non-intrusive as symbols, but convey more
> information?

And now you've hit the nail on the head ... in order to handle the extra
complexity you need additional tools ... before creating more tools, ask
your self the simple question: "Do I _need_ the additional complexity?"
... if the answer is yes, then create the tool, if the answer is no,
then you don't need to create a new tool ..

Again, this is a _practical_ matter...

>
> self error: #keyNotFound
> does not really give much information; and isn't much more difficult to
> write than:
> KeyNotFoundException new in: self; key: key; signal

 From a practical perspective how many exception handlers will be
written to handle KeyNotFoundException ... I use at:ifAbsent: when I'm
doing a look up that I think might fail ... better than writing an
exception handler ...

If there is a real need to write a handler for KeyNotFoundException,
then by all means create the class, but until you actually NEED
KeyNotFoundException, `self error: #keyNotFound` or `NotFoundException
signal: #keyNotFound` will work just fine...
>
> although the second one gives you all the contextual information that
> the first one misses.

_If_ you NEED the additional contextual information. It's just like
writing a framework that no uses ... there's nothing wrong with the idea
or the implementation, it's just that the framework didn't solve a
problem that anyone had...

If you are going to create a class, I think the least it should do is
address an real problem, not an imaginary one.

To say that "if one were to handle the KeyNotFoundException, they will
need the complete context", I prefer to say "Until one needs the
complete context of the KeyNotFoundException, don't bother creating class"

>
> What I mean mostly: what about trying to figure out why you want to
> avoid decent exception classes and tackling that problem?

Depends upon what your definition of a decent exception classes is? My
argument is simply that it is not _necessary_ to create a unique class
for every unique error condition ... I think that folks should answer
the question: "Will anyone every write an exception handler for this
exception" before creating the class ... if the answer is yes (or better
yet, I am writing code right now and need that exception) then by all
means create the class.

> Maybe we don't want classes but exception objects that can pool data
> together? Maybe a very silly idea: what about just exception "classes"
> that have dictionaries to store enough information?

That would be another way of doing things ... although using exception
classes and reasonCodes is pretty close to all that is needed...

I agree with the notion that it isn't that useful to have a single Error
class and have all errors mapped to it ... on the other hand I don't
think it is particularly useful to have an exception class for every
possible error condition ... the compromise is to provide a smallish
hierarchy of excpetion classes with fairly general structure, provide a
means for uniquely identifying every possible error condition (I think
that is important) and then add new classes to the hierarchy when a
demand for the class is found ...



Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Daniel Lyons
On Apr 13, 2011, at 5:00 PM, Dale Henrichs wrote:
> To say that "if one were to handle the KeyNotFoundException, they will need the complete context", I prefer to say "Until one needs the complete context of the KeyNotFoundException, don't bother creating class"

I hope (as an outsider) that this advice is taken seriously during this important refactoring effort.

Designing the hierarchy is very much a what-color-should-the-bike-shed-be question. Usually the way it plays out on in day-to-day use is not gratitude towards the benevolent API designer for having provided such precise and helpful exception classes or rage towards the careless API designer for making them so unhelpful. No, In my experience it is much more likely to be, swearing at the API designer for having made exception handling an important (but substantially less discoverable) part of the API that must be mastered alongside the ordinary message protocol.

A lesson from Java is that if you provide a rich, complex exception hierarchy with lots of specific exceptions, people will feel like they should be using them, even if they're never used in the system, poorly defined, or represent too broad a category (I'm looking at you, IllegalStateException!)


Daniel Lyons


Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Toon Verwaest-2
In reply to this post by Dale Henrichs
Somehow I feel like I offended someone :)

I personally don't have experience with 10'000+ classes in a system. I
do understand that's where you are coming from and do appreciate the
insight.

My personal experience has rather been the opposite until now. For
example the Pharo/Squeak classbuilder is 1 single class doing
everything. This is horrible; not just horrible because the code is
completely horrid but it's non-extensible, non-configurable,
non-reusable, contains tons of duplication _just because_ it is all put
into one big ball of mud. By decomposing the classbuilder into 4 to 10
different classes I ended up having very little methods with very little
code, and a very high level of configurability and understandability. I
now actually use this classbuilder to build anonymous classes too,
avoiding the whole problem with forgetting to copy in the format that
everyone seems to have.

And this experience was showing me that having classes for all
_relevant_ concepts actually pays off in the long run. Since you (and
others) are saying that it doesn't for exceptions; and since I don't
have enough experience there I'll take your advice into account when
writing code ;)

Toon

On 04/14/2011 01:00 AM, Dale Henrichs wrote:

> On 04/13/2011 02:58 PM, Toon Verwaest wrote:
>> Is it such a problem if you duplicate a certain exception class? At the
>> moment you'll do the same anyway by not completely writing the exact
>> same symbol.
>
> It's a simple matter of namespaces and volume of names ... with a
> large open ended namespace you are more likely to have a number of
> redundant names with slight differences in spelling showing up in
> different spots in the hierarchy...with a logically segmented
> namespace each segment will have a manageable number of names and the
> risk of duplication is reduced ... end of discussion ...
>
> 10,000 names vs 30 names ... I can easily recognize duplicates in a
> list of 30 names ... not so easy in 10,000 ... that is all ...
>
> to attempt to map every possible error condition onto a class will
> lead you to 10,000 much quicker than using reasonCodes ... that is all
> ...
>
> I don't hate classes, it is a _practical_ matter ... if _you_ would
> rather manage 10,000 names then I will say that it isn't practical ...
> I'm _not_ saying it is _wrong_, just not _practical_.
>
>>
>> And if the problem is not finding classes anymore, maybe we need a
>> better way of organizing the exception classes away from the standard
>> classes so that they are as non-intrusive as symbols, but convey more
>> information?
>
> And now you've hit the nail on the head ... in order to handle the
> extra complexity you need additional tools ... before creating more
> tools, ask your self the simple question: "Do I _need_ the additional
> complexity?" ... if the answer is yes, then create the tool, if the
> answer is no, then you don't need to create a new tool ..
>
> Again, this is a _practical_ matter...
>
>>
>> self error: #keyNotFound
>> does not really give much information; and isn't much more difficult to
>> write than:
>> KeyNotFoundException new in: self; key: key; signal
>
> From a practical perspective how many exception handlers will be
> written to handle KeyNotFoundException ... I use at:ifAbsent: when I'm
> doing a look up that I think might fail ... better than writing an
> exception handler ...
>
> If there is a real need to write a handler for KeyNotFoundException,
> then by all means create the class, but until you actually NEED
> KeyNotFoundException, `self error: #keyNotFound` or `NotFoundException
> signal: #keyNotFound` will work just fine...
>>
>> although the second one gives you all the contextual information that
>> the first one misses.
>
> _If_ you NEED the additional contextual information. It's just like
> writing a framework that no uses ... there's nothing wrong with the
> idea or the implementation, it's just that the framework didn't solve
> a problem that anyone had...
>
> If you are going to create a class, I think the least it should do is
> address an real problem, not an imaginary one.
>
> To say that "if one were to handle the KeyNotFoundException, they will
> need the complete context", I prefer to say "Until one needs the
> complete context of the KeyNotFoundException, don't bother creating
> class"
>
>>
>> What I mean mostly: what about trying to figure out why you want to
>> avoid decent exception classes and tackling that problem?
>
> Depends upon what your definition of a decent exception classes is? My
> argument is simply that it is not _necessary_ to create a unique class
> for every unique error condition ... I think that folks should answer
> the question: "Will anyone every write an exception handler for this
> exception" before creating the class ... if the answer is yes (or
> better yet, I am writing code right now and need that exception) then
> by all means create the class.
>
>> Maybe we don't want classes but exception objects that can pool data
>> together? Maybe a very silly idea: what about just exception "classes"
>> that have dictionaries to store enough information?
>
> That would be another way of doing things ... although using exception
> classes and reasonCodes is pretty close to all that is needed...
>
> I agree with the notion that it isn't that useful to have a single
> Error class and have all errors mapped to it ... on the other hand I
> don't think it is particularly useful to have an exception class for
> every possible error condition ... the compromise is to provide a
> smallish hierarchy of excpetion classes with fairly general structure,
> provide a means for uniquely identifying every possible error
> condition (I think that is important) and then add new classes to the
> hierarchy when a demand for the class is found ...
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Nicolas Cellier
We didn't say that creating classes is bad by nature, we spoke only
about compromise...
If you have a hierarchy of 1000+ class, then it makes the hierarchy
browser useless because we are flooded by unclassified information
flow.
It's fine grained mud, but from this POV it's still mud. It just means
we can't use it for finding information.
You might translate this saying "cherchez une aiguille dans une botte de foin".

The IDE still follows this late 70s classification :
category/class/protocol/method. This was tailored for a much smaller
namespace.
The only enhancement we made was to add another level like this:
 category-subcategory/class/protocol/method
We managed a x10 inflation in the namespace with such extension...
If we are to increase again our Dictionary, then we can't avoid a
reflexion on classification.

What you are proposing is to concentrate all Exception classification
in two levels:
category/class

Dale proposed a three level
category/class/method

Nicolas

2011/4/14 Toon Verwaest <[hidden email]>:

> Somehow I feel like I offended someone :)
>
> I personally don't have experience with 10'000+ classes in a system. I do
> understand that's where you are coming from and do appreciate the insight.
>
> My personal experience has rather been the opposite until now. For example
> the Pharo/Squeak classbuilder is 1 single class doing everything. This is
> horrible; not just horrible because the code is completely horrid but it's
> non-extensible, non-configurable, non-reusable, contains tons of duplication
> _just because_ it is all put into one big ball of mud. By decomposing the
> classbuilder into 4 to 10 different classes I ended up having very little
> methods with very little code, and a very high level of configurability and
> understandability. I now actually use this classbuilder to build anonymous
> classes too, avoiding the whole problem with forgetting to copy in the
> format that everyone seems to have.
>
> And this experience was showing me that having classes for all _relevant_
> concepts actually pays off in the long run. Since you (and others) are
> saying that it doesn't for exceptions; and since I don't have enough
> experience there I'll take your advice into account when writing code ;)
>
> Toon
>
> On 04/14/2011 01:00 AM, Dale Henrichs wrote:
>>
>> On 04/13/2011 02:58 PM, Toon Verwaest wrote:
>>>
>>> Is it such a problem if you duplicate a certain exception class? At the
>>> moment you'll do the same anyway by not completely writing the exact
>>> same symbol.
>>
>> It's a simple matter of namespaces and volume of names ... with a large
>> open ended namespace you are more likely to have a number of redundant names
>> with slight differences in spelling showing up in different spots in the
>> hierarchy...with a logically segmented namespace each segment will have a
>> manageable number of names and the risk of duplication is reduced ... end of
>> discussion ...
>>
>> 10,000 names vs 30 names ... I can easily recognize duplicates in a list
>> of 30 names ... not so easy in 10,000 ... that is all ...
>>
>> to attempt to map every possible error condition onto a class will lead
>> you to 10,000 much quicker than using reasonCodes ... that is all ...
>>
>> I don't hate classes, it is a _practical_ matter ... if _you_ would rather
>> manage 10,000 names then I will say that it isn't practical ... I'm _not_
>> saying it is _wrong_, just not _practical_.
>>
>>>
>>> And if the problem is not finding classes anymore, maybe we need a
>>> better way of organizing the exception classes away from the standard
>>> classes so that they are as non-intrusive as symbols, but convey more
>>> information?
>>
>> And now you've hit the nail on the head ... in order to handle the extra
>> complexity you need additional tools ... before creating more tools, ask
>> your self the simple question: "Do I _need_ the additional complexity?" ...
>> if the answer is yes, then create the tool, if the answer is no, then you
>> don't need to create a new tool ..
>>
>> Again, this is a _practical_ matter...
>>
>>>
>>> self error: #keyNotFound
>>> does not really give much information; and isn't much more difficult to
>>> write than:
>>> KeyNotFoundException new in: self; key: key; signal
>>
>> From a practical perspective how many exception handlers will be written
>> to handle KeyNotFoundException ... I use at:ifAbsent: when I'm doing a look
>> up that I think might fail ... better than writing an exception handler ...
>>
>> If there is a real need to write a handler for KeyNotFoundException, then
>> by all means create the class, but until you actually NEED
>> KeyNotFoundException, `self error: #keyNotFound` or `NotFoundException
>> signal: #keyNotFound` will work just fine...
>>>
>>> although the second one gives you all the contextual information that
>>> the first one misses.
>>
>> _If_ you NEED the additional contextual information. It's just like
>> writing a framework that no uses ... there's nothing wrong with the idea or
>> the implementation, it's just that the framework didn't solve a problem that
>> anyone had...
>>
>> If you are going to create a class, I think the least it should do is
>> address an real problem, not an imaginary one.
>>
>> To say that "if one were to handle the KeyNotFoundException, they will
>> need the complete context", I prefer to say "Until one needs the complete
>> context of the KeyNotFoundException, don't bother creating class"
>>
>>>
>>> What I mean mostly: what about trying to figure out why you want to
>>> avoid decent exception classes and tackling that problem?
>>
>> Depends upon what your definition of a decent exception classes is? My
>> argument is simply that it is not _necessary_ to create a unique class for
>> every unique error condition ... I think that folks should answer the
>> question: "Will anyone every write an exception handler for this exception"
>> before creating the class ... if the answer is yes (or better yet, I am
>> writing code right now and need that exception) then by all means create the
>> class.
>>
>>> Maybe we don't want classes but exception objects that can pool data
>>> together? Maybe a very silly idea: what about just exception "classes"
>>> that have dictionaries to store enough information?
>>
>> That would be another way of doing things ... although using exception
>> classes and reasonCodes is pretty close to all that is needed...
>>
>> I agree with the notion that it isn't that useful to have a single Error
>> class and have all errors mapped to it ... on the other hand I don't think
>> it is particularly useful to have an exception class for every possible
>> error condition ... the compromise is to provide a smallish hierarchy of
>> excpetion classes with fairly general structure, provide a means for
>> uniquely identifying every possible error condition (I think that is
>> important) and then add new classes to the hierarchy when a demand for the
>> class is found ...
>>
>>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Hernan Wilkinson-3
In reply to this post by Toon Verwaest-2
the problem is not related to technical issues (like how much machine memory you save, etc). It is related to knowledge organization...
If you have two classes that define exactly the same methods, inst var, etc, why do you have two instead of one? If you answer is "because of the name of the class", remember that names are contextualized to the place where they are used...
I mean, this is easy, just take all the places where exceptions are handle in Smalltalk and look what the handlers do with the exceptions. You will see that in almost all cases the exceptions are not used at all, the information they carry with them is not use at all... so, from a theory point of view it looks nice to have a big exception hierarchy but from the practical point of view is not only useless but also more difficult to use.
I build a system that had an exception class base on where they were signal and not handled, we end up with around 1100 exceptions... only 3 or 4 are handled directly

On Wed, Apr 13, 2011 at 6:01 PM, Toon Verwaest <[hidden email]> wrote:
I find the "managing the exception hierarchy" a bit strange... Do you really have to manage anything more than just normal classes? Every exception is related to a specific part of your code, just like other classes. What's wrong with creating hundreds of small classes wherever it's necessary? You might save a tiny bit of memory by using error codes or symbols, but I don't really see much more of a gain there, while you do gain from proper objects.

Being clear and modeling properly generally pays off in the long run. And the bit of runtime memory you save isn't really worth your while...

Or am I missing something else? I didn't really follow the whole conversation in-depth.

cheers,
Toon


On 04/13/2011 09:54 PM, Dale Henrichs wrote:
Camillo,

Hey, I _am_ old, but not _that_ old:) ... There are a couple of things that were invented in the Stone Age that have survived to today, so old ideas are not immediately bad, because they are old:)

It feels like you are creating classes that are not much more than symbols ...

I am not one to shy away from using classes when they are called for, but I am just making a practicality point ... we don't have a unique class for each character in the alphabet, but we could....we could have a unique class for every possible error condition or not ...

I think it is simply a practical answer...

I do maintain that you _should_ use some sort of test along the lines of: "Will anyone ever need to write a handler for the exception?" in your criteria for deciding when to create a class and when to use something like a "reason code" to disambiguate the signalling site...

Dale

On 04/13/2011 12:32 PM, Camillo Bruni wrote:
Perfect, I ll be there to bang heads ;).

So without "Exception" pre- or suffix seems to be nice. However I
don't see the need of using symbols over real classes. This feels
indeed like going to stone age of error handling, thats what you have
polymorphism and ExceptionSets for.

Anyway, the main idea is to make single exceptions recognizable and
not just use one single, basically meaningless, exception type.

best regards, Camillo Bruni


On 2011-04-13, at 21:22, Sven Van Caekenberghe wrote:

Thanks a lot everybody for the reactions, this could become a nice
discussion next Friday. All points raised are valid, I would like
simple names and a compact multipurpose hierarchy too.

On 13 Apr 2011, at 19:39, Dale Henrichs wrote:

Some thoughts from an old man (started programming before
exceptions of any kind were available:) ...

In the old days, error numbers had a place in the universe ...
error numbers of a certain range indicated specific errors and
the "error handlers" could check for a range or a specific error
...

Today I think there is still a place for the notion of "error
numbers".

In Smalltalk I would use Symbols instead of numbers, but the idea
would be to use a concrete exception class to identify broad
categories of error conditions (i.e., FileStreamError) and a
symbolic "reason code" to indicate the specific error (i.e.,
#fileDoesNotExist, #fileExists, #cannotDelete, etc.), that way an
error handler can be written for FileStreamError and then
specific action take with respect to which "reason code" is
involved, if such action is needed.

The main advantage of using reasonCodes over using a "class per
error condition" is that you can reduce the size of the Exception
hierarchy to a manageable size (GemStone has hundreds of error
conditions, so we've resorted to using "reason codes" to manage
the size of the hierarchy).

As Hernan hints, more often than not it is important to be very
specific about the error condition when signalling an error (a
unique error message per "per reason code" would be desirable),
but the there are very few places where the handler is going to
be that specific ...

In other words, if it is likely that programmers in the course of
using an application will be writing specific error handlers to
distinguish between the KeyNotFound and ValueNotFound condition,
then classes should be created, otherwise, the NotFoundException
could be implemented with three reason codes: #keyNotFound,
#valueNotFound, and #elementNotFound and you'd get the best of
both worlds, explicit information at the signalling site and a
much smaller and more manageable Exception class hierarchy.

Dale

On 04/13/2011 10:15 AM, Hernan Wilkinson wrote:
I think it is not a good idea to use the prefix Exception. We
do not use the word "exception" in real life, so we should not
do it on our systems. About the proposed hierarchy, the problem
with having specific exceptions is that they are important for
those who catch them, not for those who signal them. For
example, besides the name, what is the difference between
KeyNotFound or ValueNotFound? none. So, I think that the
exception hierarchy should be grown from it uses, not created
based on how or where they are signaled.

my 2 cents :-)

On Wed, Apr 13, 2011 at 1:55 PM, Miguel
Cobá<[hidden email] <mailto:[hidden email]>>
wrote:

El mié, 13-04-2011 a las 14:52 +0200, Camillo Bruni escribió:

And as Mariano pointed out, there should be a convention on
the naming: I am still not sure about suffixing the exception
classes
with
"Exception", but I guess this is a good thing to do. Though
I
must say
that I omitted it so far ;) and just put the verb there, but
that can be easily changed.

I would say no to suffixes. Analogous to announcements, they
shouldn't have the suffix. The name should be descriptive
enough and intention revealing that the suffix isn't needed in
most cases. For example, I think that

DividedByZero

is better than

DividedByZeroException

and no information is lost with the sorter name. Instead,
DivideByZero isn't clear enough to indicate that is a event
that happened.

What do you think?

-- Miguel Cobá http://twitter.com/MiguelCobaMtz
http://miguel.leugim.com.mx







-- *Hernán Wilkinson Agile Software Development, Teaching&
Coaching Mobile: +54 - 911 - 4470 - 7207 email:
[hidden email] site:
http://www.10Pines.com<http://www.10pines.com/>*














--
Hernán Wilkinson
Agile Software Development, Teaching & Coaching
Mobile: +54 - 911 - 4470 - 7207
email: [hidden email]
site: http://www.10Pines.com

Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Toon Verwaest-2
Right, so you confirm the experience of Dale.

In the case of flagging errors without classes, do you generally just
use a simple symbol, or concatenate strings to convey more details? This
last seems somehow a bad idea... but maybe if it's never caught it's not
so relevant?

cheers,
Toon

On 04/14/2011 02:03 PM, Hernan Wilkinson wrote:

> the problem is not related to technical issues (like how much machine
> memory you save, etc). It is related to knowledge organization...
> If you have two classes that define exactly the same methods, inst
> var, etc, why do you have two instead of one? If you answer is
> "because of the name of the class", remember that names are
> contextualized to the place where they are used...
> I mean, this is easy, just take all the places where exceptions are
> handle in Smalltalk and look what the handlers do with the exceptions.
> You will see that in almost all cases the exceptions are not used at
> all, the information they carry with them is not use at all... so,
> from a theory point of view it looks nice to have a big exception
> hierarchy but from the practical point of view is not only useless but
> also more difficult to use.
> I build a system that had an exception class base on where they were
> signal and not handled, we end up with around 1100 exceptions... only
> 3 or 4 are handled directly


Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Hernan Wilkinson-3


On Thu, Apr 14, 2011 at 9:08 AM, Toon Verwaest <[hidden email]> wrote:
Right, so you confirm the experience of Dale.

In the case of flagging errors without classes, do you generally just use a simple symbol, or concatenate strings to convey more details? This last seems somehow a bad idea... but maybe if it's never caught it's not so relevant?

I don't understand exactly what you mean... if you are suggesting using error codes over exceptions, no, that is not may point. Exceptions are the right tool to get rid of the repeated/error prone code you create when using error codes, there is not doubt about it.
What I'm saying is that from the handling point of view you only need to identify the exception to handle, and matching the class of the exception with identifying the exception is not the only way (I showed another way in a previous mail).
Also, categorizing exception types using subclassing does not seem to be a good idea either... it is common use now, but that does not mean it is good. Sometimes you want to categorize exceptions in a different way that your exception class hierarchy forces you, and when that happens it is really a pain.
 

cheers,
Toon


On 04/14/2011 02:03 PM, Hernan Wilkinson wrote:
the problem is not related to technical issues (like how much machine memory you save, etc). It is related to knowledge organization...
If you have two classes that define exactly the same methods, inst var, etc, why do you have two instead of one? If you answer is "because of the name of the class", remember that names are contextualized to the place where they are used...
I mean, this is easy, just take all the places where exceptions are handle in Smalltalk and look what the handlers do with the exceptions. You will see that in almost all cases the exceptions are not used at all, the information they carry with them is not use at all... so, from a theory point of view it looks nice to have a big exception hierarchy but from the practical point of view is not only useless but also more difficult to use.
I build a system that had an exception class base on where they were signal and not handled, we end up with around 1100 exceptions... only 3 or 4 are handled directly




--
Hernán Wilkinson
Agile Software Development, Teaching & Coaching
Mobile: +54 - 911 - 4470 - 7207
email: [hidden email]
site: http://www.10Pines.com

Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Camillo Bruni

On 2011-04-14, at 14:19, Hernan Wilkinson wrote:

>
>
> On Thu, Apr 14, 2011 at 9:08 AM, Toon Verwaest <[hidden email]> wrote:
> Right, so you confirm the experience of Dale.
>
> In the case of flagging errors without classes, do you generally just use a simple symbol, or concatenate strings to convey more details? This last seems somehow a bad idea... but maybe if it's never caught it's not so relevant?
>
> I don't understand exactly what you mean... if you are suggesting using error codes over exceptions, no, that is not may point. Exceptions are the right tool to get rid of the repeated/error prone code you create when using error codes, there is not doubt about it.
> What I'm saying is that from the handling point of view you only need to identify the exception to handle, and matching the class of the exception with identifying the exception is not the only way (I showed another way in a previous mail).
> Also, categorizing exception types using subclassing does not seem to be a good idea either... it is common use now, but that does not mean it is good. Sometimes you want to categorize exceptions in a different way that your exception class hierarchy forces you, and when that happens it is really a pain.

But right now that is possible by concatenating Exceptions, generating ExceptionSets, which you could even generate upfront, so complexity-wise it is the same as using symbols as identifiers in a generic Exception class.

But I agree finding the right balance of how many exception classes to use is not easy. However, we are still far from that in Pharo..., even worse, since no one uses explicit error classes no one uses them. And certainly there should be another way to catch errors than just by relying on the type / class. Sometimes it would be nice to be able to catch errors depending on the place they were thrown,  for instance only handle exceptions thrown in my own methods / my package...

And concerning the IDE, we need a lot of improvements there, the current design and functionality in Pharo at least, resembles more a system from the 70'ies than a more recent ide.
Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Philippe Marschall-2
In reply to this post by Sven Van Caekenberghe
On 04/11/2011 04:10 PM, Sven Van Caekenberghe wrote:

> Hi All,
>
> I have this idea that I would like to discuss on the next Pharo sprint and maybe start to implement if there is some consensus on it.
>
> It has been mentioned many times before on this list that Object>>#error: should be replaced by signalling specific Exceptions in as many cases as possible (or where it makes sense). Even today, there was http://code.google.com/p/pharo/issues/detail?id=3987 !
>
> I think the core system should set the example here, by defining a number of general purpose exceptions and by using them. Going over #error: senders will be a lot of work but can be done in incremental/Pharo steps.
>
> So I went over the current hierarchy, scanned quickly through their references and some #error: senders by fundamental classes and looked at some other Smalltalks. I came up with the following very rough draft of an extended hierarchy (** marks new exceptions). In between brackets are the instance variables. Of course, we have to discuss about naming, instance variables and opportunities for reuse and inheritance (could be fun).
>
> I am no expert on exceptions and would certainly like to learn more. I am probably overlooking some aspects. We have to keep this Smalltalk like, flexible, dynamic, not start mimicing other languages.
>
> Any step in this direction will be an improvement over the current situation. Really using them correctly throughout the system will take some time. Defining the hierarchy could be done rather quickly. Refactoring is always possible later on.
>
> Exception (messageText)
>   Abort
>   Error
>     ArithemticError
>       ZeroDivide (dividend)
>       FloatingPointException
>       RangeError ** (from, to)
>       NaNError **
>     FileStreamException (fileName)
>       FileDoesNotExistException (readOnly)
>       FileExistsException (fileClass)
>       CannotDeleteFileException
>       FileWriteError
>       FileReadError **
>       FileClosedException **
>       CannotAccessFileException **
>       ReadonlyFileException **
>     MessageNotUnderstood (message, receiver)
>     NonBooleanReceiver (object)
>     OutOfMemory
>     Halt
>       AssertionFailure
>       BreakPoint
>     SyntaxError ** !exists! (input, position)
>       NumberFormatException **
>     HeadlessError **
>     TimedOut ** (object, operation, timeout)
>     VerificationException
>     IllegalOperation ** (operation, object)
>     SizeMismatch (objects)
>     LowMemory ** (percentageFree)
>     SubclassResponsibility ** (message, receiver)
>     NotYetImplemented ** (message, receiver)
>     CannotInstanciate ** (class)
>     ReadOnlyObject ** (object)
>     OutOfFreeSpace ** (object, size)
>     InvalidArgument ** (message, receiver, argument)
>     NotIndexable ** (object)    
>     NoKeyedAccess ** (object)
>     NonIntegerIndex ** (receiver, index)
>     SubscriptOutOfBounds ** (receiver, index, from, to)
>     NotFoundException ** (receiver, object)
>       KeyNotFound **
>       ValueNotFound **
>       ElementNotFound **
>     StreamException (stream)
>       PositionError ** (index, from, to)
>       EndOfStream **
>       BeginOfStream **
>
> All feedback is welcome.

PrimitiveFailed for #primitiveFailed would be nice as well.

Cheers
Philippe


Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Hernan Wilkinson-3
In reply to this post by Camillo Bruni


On Thu, Apr 14, 2011 at 10:37 AM, Camillo Bruni <[hidden email]> wrote:

On 2011-04-14, at 14:19, Hernan Wilkinson wrote:

>
>
> On Thu, Apr 14, 2011 at 9:08 AM, Toon Verwaest <[hidden email]> wrote:
> Right, so you confirm the experience of Dale.
>
> In the case of flagging errors without classes, do you generally just use a simple symbol, or concatenate strings to convey more details? This last seems somehow a bad idea... but maybe if it's never caught it's not so relevant?
>
> I don't understand exactly what you mean... if you are suggesting using error codes over exceptions, no, that is not may point. Exceptions are the right tool to get rid of the repeated/error prone code you create when using error codes, there is not doubt about it.
> What I'm saying is that from the handling point of view you only need to identify the exception to handle, and matching the class of the exception with identifying the exception is not the only way (I showed another way in a previous mail).
> Also, categorizing exception types using subclassing does not seem to be a good idea either... it is common use now, but that does not mean it is good. Sometimes you want to categorize exceptions in a different way that your exception class hierarchy forces you, and when that happens it is really a pain.

But right now that is possible by concatenating Exceptions, generating ExceptionSets, which you could even generate upfront, so complexity-wise it is the same as using symbols as identifiers in a generic Exception class.

yes of course, but you still have the super-class relationship... anyway, this is not the main issue
 

But I agree finding the right balance of how many exception classes to use is not easy. However, we are still far from that in Pharo..., even worse, since no one uses explicit error classes no one uses them.

As I said, I used them in a system and the conclusion was that you don't need them... a program can do little when an exception is throw to fix the problem (but in very small cases)...  they are basically to inform the user that something went wrong and having a good description is more important than having a big exception hierarchy.
 
And certainly there should be another way to catch errors than just by relying on the type / class. Sometimes it would be nice to be able to catch errors depending on the place they were thrown,  for instance only handle exceptions thrown in my own methods / my package...

yes, that is completely true... I would be great to have a mechanism where you could automatically convert exception while the pass subsystems/layers bounderies too... that is a great research topic I think

And concerning the IDE, we need a lot of improvements there, the current design and functionality in Pharo at least, resembles more a system from the 70'ies than a more recent ide.



--
Hernán Wilkinson
Agile Software Development, Teaching & Coaching
Mobile: +54 - 911 - 4470 - 7207
email: [hidden email]
site: http://www.10Pines.com

Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Stéphane Ducasse
In reply to this post by Toon Verwaest-2
I want this class builder :)

On Apr 14, 2011, at 10:33 AM, Toon Verwaest wrote:

> Somehow I feel like I offended someone :)
>
> I personally don't have experience with 10'000+ classes in a system. I do understand that's where you are coming from and do appreciate the insight.
>
> My personal experience has rather been the opposite until now. For example the Pharo/Squeak classbuilder is 1 single class doing everything. This is horrible; not just horrible because the code is completely horrid but it's non-extensible, non-configurable, non-reusable, contains tons of duplication _just because_ it is all put into one big ball of mud. By decomposing the classbuilder into 4 to 10 different classes I ended up having very little methods with very little code, and a very high level of configurability and understandability. I now actually use this classbuilder to build anonymous classes too, avoiding the whole problem with forgetting to copy in the format that everyone seems to have.
>
> And this experience was showing me that having classes for all _relevant_ concepts actually pays off in the long run. Since you (and others) are saying that it doesn't for exceptions; and since I don't have enough experience there I'll take your advice into account when writing code ;)
>
> Toon
>
> On 04/14/2011 01:00 AM, Dale Henrichs wrote:
>> On 04/13/2011 02:58 PM, Toon Verwaest wrote:
>>> Is it such a problem if you duplicate a certain exception class? At the
>>> moment you'll do the same anyway by not completely writing the exact
>>> same symbol.
>>
>> It's a simple matter of namespaces and volume of names ... with a large open ended namespace you are more likely to have a number of redundant names with slight differences in spelling showing up in different spots in the hierarchy...with a logically segmented namespace each segment will have a manageable number of names and the risk of duplication is reduced ... end of discussion ...
>>
>> 10,000 names vs 30 names ... I can easily recognize duplicates in a list of 30 names ... not so easy in 10,000 ... that is all ...
>>
>> to attempt to map every possible error condition onto a class will lead you to 10,000 much quicker than using reasonCodes ... that is all ...
>>
>> I don't hate classes, it is a _practical_ matter ... if _you_ would rather manage 10,000 names then I will say that it isn't practical ... I'm _not_ saying it is _wrong_, just not _practical_.
>>
>>>
>>> And if the problem is not finding classes anymore, maybe we need a
>>> better way of organizing the exception classes away from the standard
>>> classes so that they are as non-intrusive as symbols, but convey more
>>> information?
>>
>> And now you've hit the nail on the head ... in order to handle the extra complexity you need additional tools ... before creating more tools, ask your self the simple question: "Do I _need_ the additional complexity?" ... if the answer is yes, then create the tool, if the answer is no, then you don't need to create a new tool ..
>>
>> Again, this is a _practical_ matter...
>>
>>>
>>> self error: #keyNotFound
>>> does not really give much information; and isn't much more difficult to
>>> write than:
>>> KeyNotFoundException new in: self; key: key; signal
>>
>> From a practical perspective how many exception handlers will be written to handle KeyNotFoundException ... I use at:ifAbsent: when I'm doing a look up that I think might fail ... better than writing an exception handler ...
>>
>> If there is a real need to write a handler for KeyNotFoundException, then by all means create the class, but until you actually NEED KeyNotFoundException, `self error: #keyNotFound` or `NotFoundException signal: #keyNotFound` will work just fine...
>>>
>>> although the second one gives you all the contextual information that
>>> the first one misses.
>>
>> _If_ you NEED the additional contextual information. It's just like writing a framework that no uses ... there's nothing wrong with the idea or the implementation, it's just that the framework didn't solve a problem that anyone had...
>>
>> If you are going to create a class, I think the least it should do is address an real problem, not an imaginary one.
>>
>> To say that "if one were to handle the KeyNotFoundException, they will need the complete context", I prefer to say "Until one needs the complete context of the KeyNotFoundException, don't bother creating class"
>>
>>>
>>> What I mean mostly: what about trying to figure out why you want to
>>> avoid decent exception classes and tackling that problem?
>>
>> Depends upon what your definition of a decent exception classes is? My argument is simply that it is not _necessary_ to create a unique class for every unique error condition ... I think that folks should answer the question: "Will anyone every write an exception handler for this exception" before creating the class ... if the answer is yes (or better yet, I am writing code right now and need that exception) then by all means create the class.
>>
>>> Maybe we don't want classes but exception objects that can pool data
>>> together? Maybe a very silly idea: what about just exception "classes"
>>> that have dictionaries to store enough information?
>>
>> That would be another way of doing things ... although using exception classes and reasonCodes is pretty close to all that is needed...
>>
>> I agree with the notion that it isn't that useful to have a single Error class and have all errors mapped to it ... on the other hand I don't think it is particularly useful to have an exception class for every possible error condition ... the compromise is to provide a smallish hierarchy of excpetion classes with fairly general structure, provide a means for uniquely identifying every possible error condition (I think that is important) and then add new classes to the hierarchy when a demand for the class is found ...
>>
>>
>
>


Reply | Threaded
Open this post in threaded view
|

Class Builder for Pharo, was Re: Improving Pharo's Exception Hierarchy

Toon Verwaest-2
Be patient, be patient ;)

I'm still very busy at the moment, but it'll get there.

We'll probably have discuss if you want to generate slot and layout
objects in the classbuilder, or if you want to replace the
instanceVariables array with real layout objects that you keep around.
We basically implemented everything around the layout objects and keep
this data in all classes; but you'll have to figure out if you want this
in Pharo or not. Decide and let me know, I'd say ;)

cheers,
Toon

On 04/14/2011 04:07 PM, Stéphane Ducasse wrote:
> I want this class builder :)


Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Hernan Wilkinson-3
In reply to this post by Toon Verwaest-2


On Thu, Apr 14, 2011 at 5:33 AM, Toon Verwaest <[hidden email]> wrote:
Somehow I feel like I offended someone :)

I personally don't have experience with 10'000+ classes in a system. I do understand that's where you are coming from and do appreciate the insight.

My personal experience has rather been the opposite until now. For example the Pharo/Squeak classbuilder is 1 single class doing everything. This is horrible; not just horrible because the code is completely horrid but it's non-extensible, non-configurable, non-reusable, contains tons of duplication _just because_ it is all put into one big ball of mud. By decomposing the classbuilder into 4 to 10 different classes I ended up having very little methods with very little code, and a very high level of configurability and understandability. I now actually use this classbuilder to build anonymous classes too, avoiding the whole problem with forgetting to copy in the format that everyone seems to have.

And this experience was showing me that having classes for all _relevant_ concepts actually pays off in the long run. Since you (and others) are saying that it doesn't for exceptions; and since I don't have enough experience there I'll take your advice into account when writing code ;)

I think you said it right here: "having classes for all _relevant_ concepts actually pays off"... 
Related to exceptions, my question is:  what are all the different concepts you have? for example, not finding a Key or not finding a Value are really different concepts? or is it the same (not finding something) that depending on the context (finding a value or a key) is what looks like they are different? if so, then there is only one concept (i.e. not finding an object), if it is a key or a value is accidental, contextual to what you are looking for.
So, I completely agree when you say "having classes for all relevant concepts"... I think we do not agree on what are the relevant concepts when we talk about exceptions...
 

Toon


On 04/14/2011 01:00 AM, Dale Henrichs wrote:
On 04/13/2011 02:58 PM, Toon Verwaest wrote:
Is it such a problem if you duplicate a certain exception class? At the
moment you'll do the same anyway by not completely writing the exact
same symbol.

It's a simple matter of namespaces and volume of names ... with a large open ended namespace you are more likely to have a number of redundant names with slight differences in spelling showing up in different spots in the hierarchy...with a logically segmented namespace each segment will have a manageable number of names and the risk of duplication is reduced ... end of discussion ...

10,000 names vs 30 names ... I can easily recognize duplicates in a list of 30 names ... not so easy in 10,000 ... that is all ...

to attempt to map every possible error condition onto a class will lead you to 10,000 much quicker than using reasonCodes ... that is all ...

I don't hate classes, it is a _practical_ matter ... if _you_ would rather manage 10,000 names then I will say that it isn't practical ... I'm _not_ saying it is _wrong_, just not _practical_.


And if the problem is not finding classes anymore, maybe we need a
better way of organizing the exception classes away from the standard
classes so that they are as non-intrusive as symbols, but convey more
information?

And now you've hit the nail on the head ... in order to handle the extra complexity you need additional tools ... before creating more tools, ask your self the simple question: "Do I _need_ the additional complexity?" ... if the answer is yes, then create the tool, if the answer is no, then you don't need to create a new tool ..

Again, this is a _practical_ matter...


self error: #keyNotFound
does not really give much information; and isn't much more difficult to
write than:
KeyNotFoundException new in: self; key: key; signal

From a practical perspective how many exception handlers will be written to handle KeyNotFoundException ... I use at:ifAbsent: when I'm doing a look up that I think might fail ... better than writing an exception handler ...

If there is a real need to write a handler for KeyNotFoundException, then by all means create the class, but until you actually NEED KeyNotFoundException, `self error: #keyNotFound` or `NotFoundException signal: #keyNotFound` will work just fine...

although the second one gives you all the contextual information that
the first one misses.

_If_ you NEED the additional contextual information. It's just like writing a framework that no uses ... there's nothing wrong with the idea or the implementation, it's just that the framework didn't solve a problem that anyone had...

If you are going to create a class, I think the least it should do is address an real problem, not an imaginary one.

To say that "if one were to handle the KeyNotFoundException, they will need the complete context", I prefer to say "Until one needs the complete context of the KeyNotFoundException, don't bother creating class"


What I mean mostly: what about trying to figure out why you want to
avoid decent exception classes and tackling that problem?

Depends upon what your definition of a decent exception classes is? My argument is simply that it is not _necessary_ to create a unique class for every unique error condition ... I think that folks should answer the question: "Will anyone every write an exception handler for this exception" before creating the class ... if the answer is yes (or better yet, I am writing code right now and need that exception) then by all means create the class.

Maybe we don't want classes but exception objects that can pool data
together? Maybe a very silly idea: what about just exception "classes"
that have dictionaries to store enough information?

That would be another way of doing things ... although using exception classes and reasonCodes is pretty close to all that is needed...

I agree with the notion that it isn't that useful to have a single Error class and have all errors mapped to it ... on the other hand I don't think it is particularly useful to have an exception class for every possible error condition ... the compromise is to provide a smallish hierarchy of excpetion classes with fairly general structure, provide a means for uniquely identifying every possible error condition (I think that is important) and then add new classes to the hierarchy when a demand for the class is found ...







--
Hernán Wilkinson
Agile Software Development, Teaching & Coaching
Mobile: +54 - 911 - 4470 - 7207
email: [hidden email]
site: http://www.10Pines.com

Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

abergel
> I think you said it right here: "having classes for all _relevant_ concepts actually pays off"...

I do not quite agree on this. Responsibility should be the driver, not the concepts.

Alexandre


> Related to exceptions, my question is:  what are all the different concepts you have? for example, not finding a Key or not finding a Value are really different concepts? or is it the same (not finding something) that depending on the context (finding a value or a key) is what looks like they are different? if so, then there is only one concept (i.e. not finding an object), if it is a key or a value is accidental, contextual to what you are looking for.
> So, I completely agree when you say "having classes for all relevant concepts"... I think we do not agree on what are the relevant concepts when we talk about exceptions...
>  
>
> Toon
>
>
> On 04/14/2011 01:00 AM, Dale Henrichs wrote:
> On 04/13/2011 02:58 PM, Toon Verwaest wrote:
> Is it such a problem if you duplicate a certain exception class? At the
> moment you'll do the same anyway by not completely writing the exact
> same symbol.
>
> It's a simple matter of namespaces and volume of names ... with a large open ended namespace you are more likely to have a number of redundant names with slight differences in spelling showing up in different spots in the hierarchy...with a logically segmented namespace each segment will have a manageable number of names and the risk of duplication is reduced ... end of discussion ...
>
> 10,000 names vs 30 names ... I can easily recognize duplicates in a list of 30 names ... not so easy in 10,000 ... that is all ...
>
> to attempt to map every possible error condition onto a class will lead you to 10,000 much quicker than using reasonCodes ... that is all ...
>
> I don't hate classes, it is a _practical_ matter ... if _you_ would rather manage 10,000 names then I will say that it isn't practical ... I'm _not_ saying it is _wrong_, just not _practical_.
>
>
> And if the problem is not finding classes anymore, maybe we need a
> better way of organizing the exception classes away from the standard
> classes so that they are as non-intrusive as symbols, but convey more
> information?
>
> And now you've hit the nail on the head ... in order to handle the extra complexity you need additional tools ... before creating more tools, ask your self the simple question: "Do I _need_ the additional complexity?" ... if the answer is yes, then create the tool, if the answer is no, then you don't need to create a new tool ..
>
> Again, this is a _practical_ matter...
>
>
> self error: #keyNotFound
> does not really give much information; and isn't much more difficult to
> write than:
> KeyNotFoundException new in: self; key: key; signal
>
> From a practical perspective how many exception handlers will be written to handle KeyNotFoundException ... I use at:ifAbsent: when I'm doing a look up that I think might fail ... better than writing an exception handler ...
>
> If there is a real need to write a handler for KeyNotFoundException, then by all means create the class, but until you actually NEED KeyNotFoundException, `self error: #keyNotFound` or `NotFoundException signal: #keyNotFound` will work just fine...
>
> although the second one gives you all the contextual information that
> the first one misses.
>
> _If_ you NEED the additional contextual information. It's just like writing a framework that no uses ... there's nothing wrong with the idea or the implementation, it's just that the framework didn't solve a problem that anyone had...
>
> If you are going to create a class, I think the least it should do is address an real problem, not an imaginary one.
>
> To say that "if one were to handle the KeyNotFoundException, they will need the complete context", I prefer to say "Until one needs the complete context of the KeyNotFoundException, don't bother creating class"
>
>
> What I mean mostly: what about trying to figure out why you want to
> avoid decent exception classes and tackling that problem?
>
> Depends upon what your definition of a decent exception classes is? My argument is simply that it is not _necessary_ to create a unique class for every unique error condition ... I think that folks should answer the question: "Will anyone every write an exception handler for this exception" before creating the class ... if the answer is yes (or better yet, I am writing code right now and need that exception) then by all means create the class.
>
> Maybe we don't want classes but exception objects that can pool data
> together? Maybe a very silly idea: what about just exception "classes"
> that have dictionaries to store enough information?
>
> That would be another way of doing things ... although using exception classes and reasonCodes is pretty close to all that is needed...
>
> I agree with the notion that it isn't that useful to have a single Error class and have all errors mapped to it ... on the other hand I don't think it is particularly useful to have an exception class for every possible error condition ... the compromise is to provide a smallish hierarchy of excpetion classes with fairly general structure, provide a means for uniquely identifying every possible error condition (I think that is important) and then add new classes to the hierarchy when a demand for the class is found ...
>
>
>
>
>
>
>
> --
> Hernán Wilkinson
> Agile Software Development, Teaching & Coaching
> Mobile: +54 - 911 - 4470 - 7207
> email: [hidden email]
> site: http://www.10Pines.com
>

--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel  http://www.bergel.eu
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.






Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Dale Henrichs
In reply to this post by Toon Verwaest-2
On 04/14/2011 01:33 AM, Toon Verwaest wrote:
> Somehow I feel like I offended someone :)

Not at all ... I like to wave my arms, talk passionately and draw all
over a white board ... all things that are difficult to do in an email:)

>
> I personally don't have experience with 10'000+ classes in a system. I
> do understand that's where you are coming from and do appreciate the
> insight.
>
> My personal experience has rather been the opposite until now. For
> example the Pharo/Squeak classbuilder is 1 single class doing
> everything. This is horrible; not just horrible because the code is
> completely horrid but it's non-extensible, non-configurable,
> non-reusable, contains tons of duplication _just because_ it is all put
> into one big ball of mud. By decomposing the classbuilder into 4 to 10
> different classes I ended up having very little methods with very little
> code, and a very high level of configurability and understandability. I
> now actually use this classbuilder to build anonymous classes too,
> avoiding the whole problem with forgetting to copy in the format that
> everyone seems to have.

Monolithic classes are difficult to maintain and hard to extend ... I am
whole heartedly in favor of using classes, just take a look at
Metacello: ~300 classes including a dozen exception classes.

My main message is that it is generally a bad idea to build a framework
when one isn't needed.

One shouldn't be shy about creating multiple classes to do a job, when
they are called for.

On the other hand, one shouldn't create a framework of classes until
such a frame work is called for.

For the Exception framework I think the following guidelines should apply:

   1. Each unique error _should_ be uniquely identified and the current
      mechanism of providing a string argument to the #error: message is
      not sufficient.
   2. Specific handlers will not be written for most errors, so it isn't
      absolutely necessary to create a unique exception class for all
      errors
   3. If specific handlers exist (doing string parsing now) or there is a
      reasonable case made that specific handlers are likely to written,
      then a unique exception class should be created.
   4. reasonCodes (within the namespace of an exception class or
      subhierarcy) can be used to uniquely identify an error condition,
      when a unique class isn't called for.
   5. In the fullness of time, if a case is found where a reasonCode
      should be turned into a unique exception class, then the class
      should be created.

These guidelines should help keep the Exception hierarchy as small as is
needed, but allow expansion as well.

Keep in mind that the primary purpose of the Exception is to allow code
to be written that automates the handling of the exception. Developers
don't need Exceptions to debug/develop applications ... the debugger
provides all of the information that a developer needs ...So the
exception is there when a developer cannot look at the stack and must
write code to report the error to a log, an end user, or take corrective
action .... for an error report, the exception class and reasonCode is
sufficient information for a developer to go back to the code and
determine the call site ...

>
> And this experience was showing me that having classes for all
> _relevant_ concepts actually pays off in the long run. Since you (and
> others) are saying that it doesn't for exceptions; and since I don't
> have enough experience there I'll take your advice into account when
> writing code ;)

Agreed 100% ... we all have to use judgment when writing our code, so
having a little more information never hurts (unless you're wacked by a
waving arm:)...

Dale



Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Miguel Cobá
El jue, 14-04-2011 a las 08:50 -0700, Dale Henrichs escribió:

> For the Exception framework I think the following guidelines should apply:
>
>    1. Each unique error _should_ be uniquely identified and the current
>       mechanism of providing a string argument to the #error: message is
>       not sufficient.
>    2. Specific handlers will not be written for most errors, so it isn't
>       absolutely necessary to create a unique exception class for all
>       errors
>    3. If specific handlers exist (doing string parsing now) or there is a
>       reasonable case made that specific handlers are likely to written,
>       then a unique exception class should be created.
>    4. reasonCodes (within the namespace of an exception class or
>       subhierarcy) can be used to uniquely identify an error condition,
>       when a unique class isn't called for.
>    5. In the fullness of time, if a case is found where a reasonCode
>       should be turned into a unique exception class, then the class
>       should be created.
>
> These guidelines should help keep the Exception hierarchy as small as is
> needed, but allow expansion as well.
>
> Keep in mind that the primary purpose of the Exception is to allow code
> to be written that automates the handling of the exception. Developers
> don't need Exceptions to debug/develop applications ... the debugger
> provides all of the information that a developer needs ...So the
> exception is there when a developer cannot look at the stack and must
> write code to report the error to a log, an end user, or take corrective
> action .... for an error report, the exception class and reasonCode is
> sufficient information for a developer to go back to the code and
> determine the call site ...
>

Very well put. I think that those guidelines will permit to evolve the
current Exception framework in Pharo and avoid ending with an
over-engineered and commite-dictated set of seldom used exception
classes.
Thanks Dale
--
Miguel Cobá
http://twitter.com/MiguelCobaMtz
http://miguel.leugim.com.mx




Reply | Threaded
Open this post in threaded view
|

Re: Improving Pharo's Exception Hierarchy

Dale Henrichs
In reply to this post by Toon Verwaest-2
On 04/14/2011 05:08 AM, Toon Verwaest wrote:
> Right, so you confirm the experience of Dale.
>
> In the case of flagging errors without classes, do you generally just
> use a simple symbol, or concatenate strings to convey more details? This
> last seems somehow a bad idea... but maybe if it's never caught it's not
> so relevant?
>

Using Sven's hierachy as a starting point and taking some cues from the
GemStone exception hierarchy, I would suggest the following (names
atarting with # are reasonCodes in the namespace of the parent exception
class, instead of a unique class):

Exception (messageText reasonCode)
   Abort
   Error
     NumericError
       #floatingPointException
       #rangeError
       #naNError
       ZeroDivide (dividend)
     FileStreamException (fileName)
       #fileDoesNotExistException
       #fileExistsException (fileClass)
       #cannotDeleteFileException
       #fileWriteError
       #fileReadError **
       #fileClosedException **
       #cannotAccessFileException **
       #readonlyFileException **
     MessageNotUnderstood (message, receiver)
     #nonBooleanReceiver (object)
     OutOfMemory < handlers?>
     ControlInterrupt
       Halt
         AssertionFailure
       BreakPoint
     CompileError
       SyntaxError ** !exists! (input, position)
         #numberFormatException **
     #headlessError **
     TimedOut ** (object, operation, timeout)
     VerificationException
     IllegalOperation ** (operation, object)
     #sizeMismatch (objects)
     #subclassResponsibility ** (message, receiver)
     #notYetImplemented ** (message, receiver)
     #cannotInstanciate ** (class)
     #readOnlyObject ** (object)
     OutOfFreeSpace ** <handlers?>
     #invalidArgument ** (message, receiver, argument)
     #notIndexable ** (object)
     #noKeyedAccess ** (object)
     #nonIntegerIndex ** (receiver, index)
     #subscriptOutOfBounds ** (receiver, index, from, to)
     NotFoundException ** (receiver, object)
       #keyNotFound **
       #valueNotFound **
       #elementNotFound **
     StreamException (stream)
       #positionError ** (index, from, to)
       EndOfStream **
       #beginOfStream **

   Notification
     Admonition
       LowMemory ** <this should be a notification not an error>

123