On Mar 9, 12:05 pm, Kay Schluehr <[EMAIL PROTECTED]> wrote: > On 9 Mrz., 04:51, Lie <[EMAIL PROTECTED]> wrote: > > > A more through implementation would start from the raiser inspecting > > the execution stack and finding whether there are any try block above > > it, if no try block exist it pass silently and if one exist it will > > check whether it have a matching except clause. This also circumvents > > a problem that simple implementation have, as described below. > > This will not be easy in particular in the presence of inheritance and > dynamism. There is no way to statically decide whether an exception > BException has the type AException and will be caught by the except > clause in > > try: > BLOCK > except AException, e: > print "SoftException %s caught"%e
> A feasible solution was to invert the try...except statement and > creating a continuation. > > catch AException, a: > print "SoftException A: %s"%a > catch BException , b: > print "SoftException B: %s"%b > ... > in: > BLOCK > > Here each SoftException is raised initially when a catch clause is > entered and a continuation is created that returns to the catch block > of the raised SoftException if required. When a SoftException is > raised within BLOCK a lookup will be made and if a corresponding > SoftException was found that was raised by a catch-clause the current > control flow will be suspended and the continuation is called. I'd rather want to avoid any syntax changes, as I wished that Soft Exception can be added to the language silently[1] so that new programmers doesn't _need_ to know about it (although knowing it could change the way they write codes to be more structured and simple). [1] Definition of silently: Codes that aren't aware of this functionality shouldn't break. Adding new syntax usually means adding keywords, making possible break in current program. On Mar 9, 12:30 pm, Steven D'Aprano <[EMAIL PROTECTED] cybersource.com.au> wrote: > On Sat, 08 Mar 2008 19:51:24 -0800, Lie wrote: > > Soft Exception > > What is "Soft Exception"? > > Soft Exception is an exception that if is unhandled, pass silently as if > > nothing happened. For example, if a variable turns into NoneType, it'll > > raise Soft Exception that it have become NoneException, programmers that > > wants to handle it can handle it with a try...except block while > > programmers that doesn't care about it (or know it won't be a problem to > > his code) can just leave the code as it is. > > > Soft Exception differs from Hard Exceptions (the regular Exception) in a > > way that Hard Exception must be handled at all cost or the program will > > be terminated while Soft Exception allow programmers not to handle it if > > they don't want to. > > I don't think that there are very many cases where exceptions can be > ignored safely. There are two main reasons for using exceptions: > > (1) Signaling an exceptional event. In that case, programmers might decide whether to raise Soft or Hard Exception. Hard Exception is much preferred. > (2) An error occurred. Which must always be handled with Hard Exception. Adding another thing (3) Informing codes above it about what's currently happening inside, the thing is just a mundane report that might be useful to codes above Which might be a useful place to use SoftExceptions > I can't think of many cases where you would wish to ignore either, and > just continue processing. The only examples I can think of are in loops, > where you are doing the same thing over and over again with just a little > change, and you wish to skip any problematic data, e.g.: > > def plot_graph(func, domain): > for x in domain: > plot(x, func(x)) > > If an error occurs in plot() for one particular x value, you would want > to ignore it and go on to the next point. But that's easy enough to do > with a regular try...except block. No, you're misunderstanding the purpose of Soft Exception, it's not for silencing errors and not so much for exceptional cases. It's for the more mundane tasks such as: from __future__ import division class SomeNumeric(object): def __div__(a, b): if b == 0: raise ZeroDivisionError ## Hard Exception, don't ignore me! if a == 0: raise ZeroNumerator ## Soft Exception f = a / b i = a // b if f == float(i): raise IntegerDivision ## Soft Exception return a // b else: raise FloatDivision ## Soft Exception return a / b Most people can ignore the ZeroNumerator, IntegerDivision, and FloatDivision exceptions (warnings) because they're excessive and unnecessary, but some people might want to catch them and do something else (especially ZeroNumerator). Practicle example, far below. The example is actually quite bad at demonstrating the purpose of Soft Exception as it is very simple while Soft Exception is generally more useful in complex operations. But I want to avoid giving complex examples since it'll be more difficult to explain the complex examples instead of the simple examples. > Simply put, you're suggesting the following two alternatives: > > Hard Exceptions: terminate the program unless explicitly silenced > Soft Exceptions: pass silently unless explicitly caught > > In this case, I agree with the Zen of Python ("import this"): > > Errors should never pass silently. > Unless explicitly silenced. That's what sloppy programmers do, silently pass errors. OTOH, Soft exceptions are not used for errors (perhaps the wording can be better phrased: must not be used for errors), they're used for events that some might have interest in, but some would consider it as normal. That's why I mentioned to think of it as a Warning. Operations that raise Soft Exceptions should be able to run normally even when the exception isn't handled (although it might generate garbage out that can be handled at later time). > The cost of explicitly silencing exceptions is tiny, the risk of misuse > of Soft Exceptions is very high, and the benefit of them is negligible. Perhaps relabeling it as Warning, and renaming raise SoftException as give Warning might make it more acceptable? And I agree that the probability for misuse is quite high, but the benefits is also quite high, it's just that you can't see it since you're not used to using such exceptions. The benefit of SoftExceptions lies mostly on the regular programmings tasks, not the exceptional programming tasks Practical Example: This example takes _case ideas_ from this simple gravity simulator http://www.pygame.org/project/617/ BUT _no line of code is taken from it_. I only give this link so you can easily know what the case is about without lengthy explanation. A particle machine. The particle machine calculates gravity created by the particles in a field. Additionaly, it clumps together two particles that happens to be near enough (less than the sum of their radiuses). The force two particle is expressing to each other is calculated with: def calculateforce(P1, P2): return (P1.mass - P2.mass) / distance(P1, P2) and this is done to every particle in the field against the current particle. And the distance is calculated by: def distance(P1, P2) return (P1.X - P2.X) ** 2 - (P1.Y - P2.Y) ** 2 The problem happens when the distance is small enough and we want to clump them together. A possible solution to this problem might be to check whether distance is less than P1.radius + P2.radius in the calculateforce. But, this obfuscate the code since we have to separate distance calculation from the main formula (see !s), and this also insist that clumping be done on force calculation level (see @s), shortly this piece of code is plain bad: def distance(P1, P2): return (P1.X - P2.X) ** 2 - (P1.Y - P2.Y) ** 2 def calculateforce(P1, P2): ## Separating this dist calculation into its own line is ## necessary if we want to check the value of dist ## Personally I think that's a bit obfuscated. ## Well known formulas should be kept to one line if possible ! dist = distance(P1, P2) if dist <= P1.radius + P2.radius: ## Calling clump() here is bad, because ## there are occasions where we only want to ## calculate force but doesn't want to ## clump it @ clump(P1, P2) else: ! return (P1.mass - P2.mass) / dist ## Codes calling calculateforce() # Note: this code is located inside a loop F = calculateforce(P1, P2) # Do something else, acceleration calculation, movement calculations, etc A better refactoring would be like this, but this requires calculating distance twice (see !s): def distance(P1, P2): return (P1.X - P2.X) ** 2 - (P1.Y - P2.Y) ** 2 def calculateforce(P1, P2): ## Here distance is calculated once ! return (P1.mass - P2.mass) / distance(P1, P2) ## Codes calling calculateforce() # Note: this code is located inside a loop ## Here distance is calculated again ! if distance(P1, P2) <= P1.radius + P2.radius: clump(P1, P2) break F = calculateforce(P1, P2) # Do something else, acceleration calculation, movement calculations, etc A much better solution would be to use SoftException def distance(P1, P2): D = (P1.X - P2.X) ** 2 - (P1.Y - P2.Y) ** 2 if D <= P1.radius + P2.radius: raise Collision return D def calculateforce(P1, P2): try: F = (P1.mass - P2.mass) / distance(P1, P2) except Collision: raise ## Codes calling calculateforce() # Note: this code is located inside a loop try: F = calculateforce(P1, P2) except Collision: clump(P1, P2) break # Calculate the next particle pair else: # Do something else, acceleration calculation, # speed calculation, movement calculations, etc This results in a cleaner code. And it also allow _other part of codes_ that uses calculate distance and force to easily ignore or handle the Collision Exception. If this code had used Hard Exception, other codes would have to explicitly silence the exception or the program terminates. That would be too much since Collision is technically not an Error, but just a normal events that you might be interested to know. Soft Exception allows events of interest to be noticed or be ignored depending on the requirement. It's like a notice board: In the notice board, there are notices about the Maths Test next week, which you must not ignore (Hard Exception), but there are also notices about Part-time Job Advertisement, if you're interested about it you can look at it further, else you could just ignore it and do nothing (Soft Exception) -- http://mail.python.org/mailman/listinfo/python-list