Condition signals and restarts, resumable exceptions (was: Comparison with False - something I don't understand)

2010-12-09 Thread Teemu Likonen
* 2010-12-06 00:14 (-0800), Paul Rubin wrote:

 You know, I've heard the story from language designers several times
 over, that they tried putting resumable exceptions into their
 languages and it turned out to be a big mess, so they went to
 termination exceptions that fixed the issue. Are there any languages
 out there with resumable exceptions?

As some people have pointer out Common Lisp is one of those languages. I
don't know anything about language design, I'm just a hobbyist
programmer, but I think Common Lisp's condition system and its restarts
are straight-forward and easy to understand from programmer's point of
view.

Here's the relevant chapter in Peter Seibel's Practical Common Lisp:

http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-08 Thread OKB (not okblacke)
Mark Wooding wrote:
 Any code called from within the `with handler' context will (unless
 overridden) cause a call `toy(x, 0)' to return 42.  Even if the `with
 handler' block calls other functions and so on.  Note also that the
 expression of this is dynamically further from where the error is
 signalled than the resume point (which is within the same function).
 You can't do this with `try' ... `except'.  Which was, of course, the
 point.

This is an interesting setup, but I'm not sure I see why you need 
it.  If you know that, in a particular context, you want toy(x, 0) to 
result in 42 instead of ZeroDivisionError, why not just define

safeToy(x, y):
try:
retVal = toy(x, y)
except ZeroDivisionError:
retVal = 42
return retVal

. . . and then call safeToy instead of toy in those contexts?

-- 
--OKB (not okblacke)
Brendan Barnwell
Do not follow where the path may lead.  Go, instead, where there is
no path, and leave a trail.
--author unknown
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-08 Thread Mark Wooding
OKB (not okblacke) brennospamb...@nobrenspambarn.net writes:

   This is an interesting setup, but I'm not sure I see why you need 
 it.  If you know that, in a particular context, you want toy(x, 0) to 
 result in 42 instead of ZeroDivisionError, 

... and that's the point.  You don't know whether you'll need it at the
call site.  Something further up has decided that, in its context, 42
shall be the magic value returned.  In some other context, there
shouldn't be a magic value, and the exception should terminate the
program.

My toy example was just that: a minimal example showing the machinery in
action.  The value of separating out exception handling like this is
only apparent if there's a fair amount of code in between the policy
(`return 42') and the site where the exception is signalled.

Small examples of powerful abstractions aren't very convincing: a small
example trivially doesn't require powerful abstraction.  Sorry.

-- [mdw]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-06 Thread Paul Rubin
m...@distorted.org.uk (Mark Wooding) writes:
 The most obvious improvement is resumable exceptions.

You know, I've heard the story from language designers several times
over, that they tried putting resumable exceptions into their languages
and it turned out to be a big mess, so they went to termination
exceptions that fixed the issue.  Are there any languages out there with
resumable exceptions?  Escaping to a debugger doesn't really count as
that.  I guess one way to do it would be call a coroutine to handle the
exception, and either continue or unwind after the continue returns, but
doing it in a single-threaded system just seems full of hazards.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-06 Thread Steve Holden
On 12/6/2010 9:14 AM, Paul Rubin wrote:
 m...@distorted.org.uk (Mark Wooding) writes:
 The most obvious improvement is resumable exceptions.
 
 You know, I've heard the story from language designers several times
 over, that they tried putting resumable exceptions into their languages
 and it turned out to be a big mess, so they went to termination
 exceptions that fixed the issue.  Are there any languages out there with
 resumable exceptions?  Escaping to a debugger doesn't really count as
 that.  I guess one way to do it would be call a coroutine to handle the
 exception, and either continue or unwind after the continue returns, but
 doing it in a single-threaded system just seems full of hazards.

I seem to remember PL/1 has resumable exceptions, but I don't ever
remember finding a real use for them. And it's so long since I used PL/1
I may be mistaken.

regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
PyCon 2011 Atlanta March 9-17   http://us.pycon.org/
See Python Video!   http://python.mirocommunity.org/
Holden Web LLC http://www.holdenweb.com/

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-06 Thread Lie Ryan
On 12/05/10 15:52, Tim Harig wrote:
 On 2010-12-05, Tim Harig user...@ilthio.net wrote:
 Another, questionable but useful use, is to ignore the complex accounting
 of your position inside of a complex data structure.  You can continue
 moving through the structure until an exception is raised indicating
 that you have reached a boundary of the structure.
 
 Here is another example in this vein.  

I had another example where using Exception as a control structure
proves to be the most elegant solution.

The problem was a logic puzzle solver (e.g. for Sudoku, Einstein's Logic
problem, etc). The algorithm used is recursive backtracking solver (yes,
I know there are more efficient constraint-based solver, but that's
besides the point).

The function modifies the `puzzle` list in-place such that after the
call `puzzle` list will contain the solution to the puzzle (if any
exists). The solving in-place is important since this solver thread
runs in a solver thread and there is another drawing thread that
draws the currently tested board asynchronously. This means we do not
make a copy of the game board. No locking is done, since it is fine for
the drawing thread to draw malformed board, and we do not want to
compromise the solver's thread's speed.

The two versions of using return value and exception:

def solve_return(puzzle, index):
 return True when puzzle is solved,
return False when backtracking or when no solution exists

# recursion base case
if all cells are filled and puzzle does not violate game rules:
return True # solution found

if puzzle violates game rules:
return False # backtrack

if puzzle[index] is unfilled:
for i in possible_candidates(puzzle, index):
puzzle[index] = i
if solve(puzzle, index+1):
# solution already found, unwinding the stack
return True

# all candidates failed, backtrack
puzzle[r][c] = unfilled
return False
else: # the current cell is part of the base clue
return solve(puzzle, index+1) # skip it

def main_return():
puzzle = [...]
if solve_return(puzzle, 0):
print('solution found')
else:
print('no solution found')

def solve_raise(puzzle, index):
 no return value
throws SolutionFound when solution is found

# recursion base case
if all cells are filled and puzzle does not violate game rules:
raise SolutionFound

if puzzle[index] is unfilled:
for i in possible_candidates(puzzle, index):
puzzle[index] = i
if puzzle does not violate game rules:
solve(puzzle, index+1)

# all candidates failed, backtrack
puzzle[r][c] = unfilled
else: # the current cell is part of the base clue
solve(puzzle, index+1) # skip it

def main_raise():
puzzle = [...]
try:
solve_raise(puzzle, 0)
except SolutionFound:
print('solution found')
else:
print('no solution found')


Personally, I've found the logic in the exception version clearer than
the return version. Also, the exception version is easier to extend, if
I wanted to add a smarter algorithm that can deterministically infer
certain cell's value (this creates indirect recursion, solve() may call
either infer() or solve() which may call either infer() or solve()), it
can work beside the existing mechanism without explicitly handling the
return flag when a solution is found.

If we suppose that end-of-line (e.g. the semicolon, in C-like language)
is a single-step forward control structure, the if-statement is a n-step
forward control structure, and looping is a n-step backward control
structure. Now, if we suppose function call as a single-step downward
control structure, and function return as a single-step upward control
structure, then exception is a n-step upward control structure. It
throws control upwards of the function call stack, while doing cleanup
along its way up.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-06 Thread Mel
Paul Rubin wrote:

 m...@distorted.org.uk (Mark Wooding) writes:
 The most obvious improvement is resumable exceptions.
 
 You know, I've heard the story from language designers several times
 over, that they tried putting resumable exceptions into their languages
 and it turned out to be a big mess, so they went to termination
 exceptions that fixed the issue.  Are there any languages out there with
 resumable exceptions?  Escaping to a debugger doesn't really count as
 that.  I guess one way to do it would be call a coroutine to handle the
 exception, and either continue or unwind after the continue returns, but
 doing it in a single-threaded system just seems full of hazards.

Apparently, at the end of his research, Alan Turing was trying out the idea 
of 'oracles', where a computable process would have access to an 
uncomputable process to get particular results.  I would imagine that the 
idea here was to clarify what this would do to the computable process.  If 
he had lived, I doubt that Turing would have built an oracle, but the idea 
does live on in interactive debuggers.

It would seem if some situation has arisen that can be fixed by code, then 
you can just run that code there and then.  Then 'resumable exceptions' just 
become a kind of subroutine call, perhaps like the triggers in SQL.

Mel.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-06 Thread John Nagle

On 12/2/2010 10:09 AM, Paul Rubin wrote:

MRABpyt...@mrabarnett.plus.com  writes:

When writing the C code for the new regex module I thought that it
would've been easier if I could've used exceptions to propagate errors
and unwind the stack, instead of having to return an error code which
had to be checked by the caller, and then have the caller explicitly
return an error code to /its/ caller.


That's called longjmp.


Automatic garbage collection would also have been nice.


alloca might help.


   If you want proper exception unwinding, use C++, which
has it.  longjmp is a hack from the PDP-11 era.

John Nagle

--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-06 Thread Martin Gregorie
On Mon, 06 Dec 2010 09:54:46 -0800, Dennis Lee Bieber wrote:

 On Mon, 06 Dec 2010 00:14:11 -0800, Paul Rubin no.em...@nospam.invalid
 declaimed the following in gmane.comp.python.general:
 
 
 exceptions that fixed the issue.  Are there any languages out there
 with resumable exceptions?  Escaping to a debugger doesn't really count
 as
 
   Visual BASIC 6
 
 -=-=-=-=-
 On Error GoTo line

 REM Actions to sort out the error
 RESUME

   Enables the error-handling routine that starts at line
 specified in the required line argument. The line argument is any line
 label or line number. If a run-time error occurs, control branches to
 line, making the error handler active. The specified line must be in the
 same procedure as the On Error statement; otherwise, a compile-time
 error occurs.
 
Any BASIC that implements ON ERROR (i.e. just about all of them) will do 
this, not just VB.


-- 
martin@   | Martin Gregorie
gregorie. | Essex, UK
org   |
-- 
http://mail.python.org/mailman/listinfo/python-list


Resumable exceptions bad: (was Re: Comparison with False - something I don't understand)

2010-12-06 Thread John Nagle

On 12/6/2010 12:40 AM, Steve Holden wrote:

On 12/6/2010 9:14 AM, Paul Rubin wrote:

m...@distorted.org.uk (Mark Wooding) writes:

The most obvious improvement is resumable exceptions.


You know, I've heard the story from language designers several times
over, that they tried putting resumable exceptions into their languages
and it turned out to be a big mess, so they went to termination
exceptions that fixed the issue.  Are there any languages out there with
resumable exceptions?  Escaping to a debugger doesn't really count as
that.  I guess one way to do it would be call a coroutine to handle the
exception, and either continue or unwind after the continue returns, but
doing it in a single-threaded system just seems full of hazards.


I seem to remember PL/1 has resumable exceptions, but I don't ever
remember finding a real use for them. And it's so long since I used PL/1
I may be mistaken.


Resumable exceptions were a popular idea in the early days of 
programming.  LISP, PL/I, and early COBOL had constructs which

could be considered resumable exceptions.  They didn't work out
well, because the exception handler gets control in an ambiguous
situation, perhaps in the middle of an expression.  Changing
the state of the execution, then returning, can leave the program
in an invalid state.

Signal handling has many of the same problems.  A POSIX signal
is a forced subroutine call while something else is going on,
which is in itself a weird concept.  That's what a resumable
exception looks like.  CPython has a terrible time with signal
handling.  See http://www.dabeaz.com/python/UnderstandingGIL.pdf;
for the whole ugly mess.  That's why control-C won't terminate
multi-thread programs, among other things.

Unwinding cleanly from a signal is difficult, but possible
with proper CPU and compiler design.  It's done right in Ada, and
in Visual C++ for x86 on Windows.  Only some CPUs support exact
floating point exceptions, where you're guaranteed that the
exception comes in at the point where the problem occurred.
In modern superscalar CPUs, the exception comes in several
instructions after the problem was detected.  In x86 type
CPUs, the CPU hardware in the retirement unit backs up the
CPU state to the point at which the exception was detected.
PowerPC and SPARC CPUs do not do this; if you need exactness
in exception position on them, you have to put in fence instructions
to stop lookahead.  This costs performance.

As a result, C code which unwinds from signals via longjmp
is not portable.
See 
https://www.securecoding.cert.org/confluence/display/seccode/SIG32-C.+Do+not+call+longjmp%28%29+from+inside+a+signal+handler;

Nor is changing the program state from inside a signal handler.
You're not entirely sure, on many CPUs, where control is at the
point the signal came in.

(In a physics simulator, I once had to handle floating point
overflow, which indicated that the computation had to be backed
up and rerun with a smaller time step.  It's possible to do this
safely under Windows on x86 if you read all the appropriate documents.
It's not portable.  That's why I'm aware of this mess.)

So that's why resumable exceptions are a bad idea.

John Nagle
--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-06 Thread Mark Wooding
Paul Rubin no.em...@nospam.invalid writes:

 You know, I've heard the story from language designers several times
 over, that they tried putting resumable exceptions into their languages
 and it turned out to be a big mess, so they went to termination
 exceptions that fixed the issue.

That seems very surprising to me.

 Are there any languages out there with resumable exceptions?

Common Lisp and Smalltalk spring to mind.  It's fairly straightforward
to write one in Scheme.  (Actually, implementing the Common Lisp one in
terms of fluids, closures and blocks isn't especially difficult.)

 Escaping to a debugger doesn't really count as that.

Indeed not.

 I guess one way to do it would be call a coroutine to handle the
 exception, and either continue or unwind after the continue returns,
 but doing it in a single-threaded system just seems full of hazards.

It seems pretty straightforward to me.  Handlers are simply closures;
the registered handlers are part of the prevailing dynamic context.
When an exception occurs, you invoke the handlers, most-recently
registered first.  A handler that returns normally can be thought of as
`declining' to handle the exception; a handler that explicitly transfers
control elsewhere can be thought of as having handled it.

To make this work, all you need is:

  * a fluid list (i.e., one which is part of the dynamic context) of
handlers, which you can build in pure Python if you try hard enough
(see below);

  * closures to represent handlers, which Python has already, and;

  * a nonlocal transfer mechanism, and a mechanism like try ... finally
to allow functions to clean up if they're unwound.

We can actually come up with a nonlocal transfer if we try, by abusing
exceptions.

[The code in this article is lightly tested, but probably contains
stupid bugs.  Be careful.]

class block (object):
  
  Context manager for escapable blocks.

  Write

with block() as escape:
  ...

  Invoking the `escape' function causes the context body to exit
  immediately.  Invoking the `escape' function outside of the
  block's dynamic context raises a ValueError.
  
  def __init__(me):
me._tag = None
  def _escape(me, value = None):
if me._tag is None:
  raise ValueError, 'defunct block'
me.result = value
raise me._tag
  def __enter__(me, value = None):
if me._tag:
  raise ValueError, 'block already active'
me._tag = type('block tag', (BaseException,), {})
me.result = value
return me._escape
  def __exit__(me, ty, val, tb):
tag, me._tag = me._tag, None
return ty is tag

This is somewhat brittle, since some intervening context might capture
the custom exception we're using, but I don't think we can do
significantly better.

Implementing fluids badly is easy.  Effectively what we'd do to bind a
fluid dynamically is

try:
  old, fluid = fluid, new
  ...
finally:
  fluid = old

but this is visible in other threads.  The following will do the job in
a multithreaded environment.

import threading as T
import weakref as W

class FluidBinding (object):
  Context object for fluid bindings.
  def __init__(me, fluid, value):
me.fluid = fluid
me.value = value
  def __enter__(me):
me.fluid._bind(me.value)
  def __exit__(me, ty, val, tb):
me.fluid._unbind()

class Fluid (object):
  
  Represents a fluid variable, i.e., one whose binding respects
  the dynamic context rather than the lexical context.

  Read and write the Fluid through the `value' property.

  The global value is shared by all threads.  To dynamically
  bind the fluid, use the context manager `binding':

  with myfluid.binding(NEWVALUE):
...

  The binding is visible in functions called MAP within the
  context body, but not in other threads.
  

  _TLS = T.local()
  _UNBOUND = ['fluid unbound']
  _OMIT = ['fluid omitted']

  def __init__(me, value = _UNBOUND):

Iinitialze a fluid, optionally setting the global value.

me._value = value

  @property
  def value(me):

Return the current value of the fluid.

Raises AttributeError if the fluid is currently unbound.

try:
  value, _ = me._TLS.map[me]
except (AttributeError, KeyError):
  value = me._value
if value == me._UNBOUND:
  raise AttributeError, 'unbound fluid'
return value
  @value.setter
  def value(me, 

Re: Comparison with False - something I don't understand

2010-12-06 Thread Carl Banks
On Dec 6, 12:58 pm, m...@distorted.org.uk (Mark Wooding) wrote:
 Paul Rubin no.em...@nospam.invalid writes:
  You know, I've heard the story from language designers several times
  over, that they tried putting resumable exceptions into their languages
  and it turned out to be a big mess, so they went to termination
  exceptions that fixed the issue.

 That seems very surprising to me.

  Are there any languages out there with resumable exceptions?

 Common Lisp and Smalltalk spring to mind.  It's fairly straightforward
 to write one in Scheme.  (Actually, implementing the Common Lisp one in
 terms of fluids, closures and blocks isn't especially difficult.)

  Escaping to a debugger doesn't really count as that.

 Indeed not.

  I guess one way to do it would be call a coroutine to handle the
  exception, and either continue or unwind after the continue returns,
  but doing it in a single-threaded system just seems full of hazards.

 It seems pretty straightforward to me.  Handlers are simply closures;
 the registered handlers are part of the prevailing dynamic context.
 When an exception occurs, you invoke the handlers, most-recently
 registered first.  A handler that returns normally can be thought of as
 `declining' to handle the exception; a handler that explicitly transfers
 control elsewhere can be thought of as having handled it.

 To make this work, all you need is:

   * a fluid list (i.e., one which is part of the dynamic context) of
     handlers, which you can build in pure Python if you try hard enough
     (see below);

   * closures to represent handlers, which Python has already, and;

   * a nonlocal transfer mechanism, and a mechanism like try ... finally
     to allow functions to clean up if they're unwound.

 We can actually come up with a nonlocal transfer if we try, by abusing
 exceptions.

 [The code in this article is lightly tested, but probably contains
 stupid bugs.  Be careful.]

         class block (object):
           
           Context manager for escapable blocks.

           Write

                 with block() as escape:
                   ...

           Invoking the `escape' function causes the context body to exit
           immediately.  Invoking the `escape' function outside of the
           block's dynamic context raises a ValueError.
           
           def __init__(me):
             me._tag = None
           def _escape(me, value = None):
             if me._tag is None:
               raise ValueError, 'defunct block'
             me.result = value
             raise me._tag
           def __enter__(me, value = None):
             if me._tag:
               raise ValueError, 'block already active'
             me._tag = type('block tag', (BaseException,), {})
             me.result = value
             return me._escape
           def __exit__(me, ty, val, tb):
             tag, me._tag = me._tag, None
             return ty is tag

 This is somewhat brittle, since some intervening context might capture
 the custom exception we're using, but I don't think we can do
 significantly better.

 Implementing fluids badly is easy.  Effectively what we'd do to bind a
 fluid dynamically is

         try:
           old, fluid = fluid, new
           ...
         finally:
           fluid = old

 but this is visible in other threads.  The following will do the job in
 a multithreaded environment.

         import threading as T
         import weakref as W

         class FluidBinding (object):
           Context object for fluid bindings.
           def __init__(me, fluid, value):
             me.fluid = fluid
             me.value = value
           def __enter__(me):
             me.fluid._bind(me.value)
           def __exit__(me, ty, val, tb):
             me.fluid._unbind()

         class Fluid (object):
           
           Represents a fluid variable, i.e., one whose binding respects
           the dynamic context rather than the lexical context.

           Read and write the Fluid through the `value' property.

           The global value is shared by all threads.  To dynamically
           bind the fluid, use the context manager `binding':

                   with myfluid.binding(NEWVALUE):
                     ...

           The binding is visible in functions called MAP within the
           context body, but not in other threads.
           

           _TLS = T.local()
           _UNBOUND = ['fluid unbound']
           _OMIT = ['fluid omitted']

           def __init__(me, value = _UNBOUND):
             
             Iinitialze a fluid, optionally setting the global value.
             
             me._value = value

           @property
           def value(me):
             
             Return the current value of the fluid.

             Raises AttributeError if the fluid is currently unbound.
             
             try:
               value, _ = me._TLS.map[me]
             except (AttributeError, KeyError):
               value = 

Re: Comparison with False - something I don't understand

2010-12-06 Thread Carl Banks
On Dec 6, 2:42 pm, Carl Banks pavlovevide...@gmail.com wrote:
 Or, you could just put your try...finally inside a loop.


er, try...except


Carl Banks
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-06 Thread Mark Wooding
Carl Banks pavlovevide...@gmail.com writes:

 On Dec 6, 12:58 pm, m...@distorted.org.uk (Mark Wooding) wrote:
          def toy(x, y):
            r = restart('use-value')
            with r:
              if y == 0:
                error(ZeroDivisionError())
              r.result = x/y
            return r.result
 
          def example():
            def zd(exc):
              if not isinstance(exc, ZeroDivisionError):
                return
              r = find_restart('use-value')
              if not r: return
              r.invoke(42)
            print toy(5, 2)
            with handler(zd):
              print toy(1, 0)

 You could do that.

 Or, you could just put your try...finally inside a loop.

[You correct `finally' to `except' in a follow-up.]

I think you've missed the point almost entirely.

Any code called from within the `with handler' context will (unless
overridden) cause a call `toy(x, 0)' to return 42.  Even if the `with
handler' block calls other functions and so on.  Note also that the
expression of this is dynamically further from where the error is
signalled than the resume point (which is within the same function).
You can't do this with `try' ... `except'.  Which was, of course, the
point.

-- [mdw]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-06 Thread Nobody
On Mon, 06 Dec 2010 08:32:18 -0500, Mel wrote:

 Apparently, at the end of his research, Alan Turing was trying out the idea 
 of 'oracles', where a computable process would have access to an 
 uncomputable process to get particular results.  I would imagine that the 
 idea here was to clarify what this would do to the computable process.  If 
 he had lived, I doubt that Turing would have built an oracle, but the idea 
 does live on in interactive debuggers.

The oracle concept was introduced quite early on in Turing's work, late
1930s. The idea is to examine the complexity of problems relative to other
problems. E.g. if you have a Turing machine with access to an oracle which
can solve some NP-complete problem, you can analyse the complexity of
solving other NP-complete problems in that context.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-05 Thread Paul Rubin
Tim Harig user...@ilthio.net writes:
 The fact that I bothered to create classes for the dice and roles, rather
 then simply iterating over a list of numbers,  should tell you that I
 produced was of a far more flexible nature; including the support for
 roles with dice having different numbers of sides.

from itertools import product
def n_sided_die(n): return xrange(1, n+1)

# make one 3-sided die, one 4-sided die, and one 5-sided die
dice = (n_sided_die(3), n_sided_die(4), n_sided_die(5))
for roll in product(*dice):
print roll

 I merely posted a simplied description of the dice-role objects
 because I thought that it demonstrated how exceptions can provide
 eligance of control for situations that don't involve what would
 traditionally be defined as an error.

Exceptions (though sometimes necessary) are messy and I'm having a hard
time trying to envision that code being cleaner with them than without
them.  If you post the actual code maybe that will help me understand.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-05 Thread Tim Harig
On 2010-12-05, Paul Rubin no.em...@nospam.invalid wrote:
 Tim Harig user...@ilthio.net writes:
 The fact that I bothered to create classes for the dice and roles, rather
 then simply iterating over a list of numbers,  should tell you that I
 produced was of a far more flexible nature; including the support for
 roles with dice having different numbers of sides.

 from itertools import product
 def n_sided_die(n): return xrange(1, n+1)

 # make one 3-sided die, one 4-sided die, and one 5-sided die
 dice = (n_sided_die(3), n_sided_die(4), n_sided_die(5))
 for roll in product(*dice):
 print roll

Notice that you had to change the structure of your program to accomodate
the new possiblity; and, if I throw further requirements at you, you
will have to change them again.  I didn't want that.  What the dice
returned may or may not have returned an easy to compute sequence.
In fact, for all of the rest of the logic cared, the dice could have
computed their value from a previous role of another dice.  All of the
logic of about what the dice may have returned when asked for their
value and how they derived, was encapsilated in the dice themselves.
It did not need to be known anywhere else in the program logic.

The DSL effectively provided a way do define how the dice decided how
to increment themselves, how to choose the value that they returned for
their face, and how to know when they could no longer be incremented.
The DSL parser generated the dice set from the description given.
Creating new dice objects was much easier then attempting to change the
logic of how they were rolled.

 I merely posted a simplied description of the dice-role objects
 because I thought that it demonstrated how exceptions can provide
 eligance of control for situations that don't involve what would
 traditionally be defined as an error.

 Exceptions (though sometimes necessary) are messy and I'm having a hard
 time trying to envision that code being cleaner with them than without
 them.  If you post the actual code maybe that will help me understand.

Let me get this straight, the same person that was trying to tell me
setjmp/longjmp weren't messy thinks exceptions are messy?  I have used
both.  I much prefer the exceptions.  I not have to code here to post.

The cleanliness of using the exception and calling the dice increments
recursively, was that there was no need to figure out which dice needed
to be incremented whenever the first die needed to be reset.  When a dice
needed to be reset, it would raise an exception.  This exception would
rise through the recursion stack, and thus through the dice, resetting
each along the way until it found the one which needed to be incremented
or raised past the top call indicating that all of the combinations has
been exhausted.  There, once the reset condition for the previous dice
had been effectively handled, it would be supprested. 

Had this been done using in band data:

1. The roll object would have needed logic to determine when
a reset condition needed to take place, effectively
leaking some of the logic from the dice object to the
role object.

2. The roll object would have needed logic to determine how to
follow the dice which needed to be reset until it found
which one needed incrementing.  Once again, this logic
was better left to the dice walking the resets was
automatically handled by the progression of the exception.

Even if it wasn't an error, the resets were effectively a exceptional
condition from the normal flow of the role object (the primary flow simply
being to increment the first die).  By using exceptions, I effectively
isolated each into its own separate independent flow; and, because they
where called separatly, neither needed to have control conditions to detect
which was needed.  They simply allowed the dice object to decide.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-05 Thread Tim Harig
On 2010-12-05, Tim Harig user...@ilthio.net wrote:
 On 2010-12-05, Paul Rubin no.em...@nospam.invalid wrote:
 Tim Harig user...@ilthio.net writes:
 The fact that I bothered to create classes for the dice and roles, rather
 then simply iterating over a list of numbers,  should tell you that I
 produced was of a far more flexible nature; including the support for
 roles with dice having different numbers of sides.

 from itertools import product
 def n_sided_die(n): return xrange(1, n+1)

 # make one 3-sided die, one 4-sided die, and one 5-sided die
 dice = (n_sided_die(3), n_sided_die(4), n_sided_die(5))
 for roll in product(*dice):
 print roll

 Notice that you had to change the structure of your program to accomodate
 the new possiblity; and, if I throw further requirements at you, you
 will have to change them again.  I didn't want that.  What the dice
 returned may or may not have returned an easy to compute sequence.
 In fact, for all of the rest of the logic cared, the dice could have
 computed their value from a previous role of another dice.  All of the
 logic of about what the dice may have returned when asked for their
 value and how they derived, was encapsilated in the dice themselves.
 It did not need to be known anywhere else in the program logic.

 The DSL effectively provided a way do define how the dice decided how
 to increment themselves, how to choose the value that they returned for
 their face, and how to know when they could no longer be incremented.
 The DSL parser generated the dice set from the description given.
 Creating new dice objects was much easier then attempting to change the
 logic of how they were rolled.

 I merely posted a simplied description of the dice-role objects
 because I thought that it demonstrated how exceptions can provide
 eligance of control for situations that don't involve what would
 traditionally be defined as an error.

 Exceptions (though sometimes necessary) are messy and I'm having a hard
 time trying to envision that code being cleaner with them than without
 them.  If you post the actual code maybe that will help me understand.

 Let me get this straight, the same person that was trying to tell me
 setjmp/longjmp weren't messy thinks exceptions are messy?  I have used
 both.  I much prefer the exceptions.  I not have to code here to post.

 The cleanliness of using the exception and calling the dice increments
 recursively, was that there was no need to figure out which dice needed
 to be incremented whenever the first die needed to be reset.  When a dice
 needed to be reset, it would raise an exception.  This exception would
 rise through the recursion stack, and thus through the dice, resetting
 each along the way until it found the one which needed to be incremented
 or raised past the top call indicating that all of the combinations has
 been exhausted.  There, once the reset condition for the previous dice
 had been effectively handled, it would be supprested. 

 Had this been done using in band data:

   1. The roll object would have needed logic to determine when
   a reset condition needed to take place, effectively
   leaking some of the logic from the dice object to the
   role object.

   2. The roll object would have needed logic to determine how to
   follow the dice which needed to be reset until it found
   which one needed incrementing.  Once again, this logic
   was better left to the dice walking the resets was
   automatically handled by the progression of the exception.

 Even if it wasn't an error, the resets were effectively a exceptional
 condition from the normal flow of the role object (the primary flow simply
 being to increment the first die).  By using exceptions, I effectively
 isolated each into its own separate independent flow; and, because they
 where called separatly, neither needed to have control conditions to detect
 which was needed.  They simply allowed the dice object to decide.

Okay, it occures to me that you don't really need to see much to know what was
going on, here is the basic idea of how the role function of the object would
have looked like:

def role(self, dice):

try:
self.role(dice.previous())
except diceReset:
dice.increment()
except endOfDice:
raise diceReset
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-05 Thread Tim Chase

On 12/04/2010 11:42 PM, Steven D'Aprano wrote:

On Sun, 05 Dec 2010 04:13:02 +, Tim Harig wrote:
str.find is more troublesome, because the sentinel -1 doesn't propagate
and is a common source of errors:

result = string[string.find(delim):]

will return a plausible-looking but incorrect result if delim is missing
from string. But the convenience and familiarity of str.find means it
will probably be around forever.


Fortunately, string objects offer both .find() and .index() so 
you can choose whether you want sentinels or exceptions according 
to your use-case.


-tkc




--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-05 Thread Martin v. Loewis
 result = myfunction (vars) 
 
 if not result:
 # error condition
 
 Now above I first realized that the function can also return an empty 
 list under some conditions and so changed it to

If your function returns a list when successful, it should not return
False in the error case. Instead, it should return None (indicating that
there is no list).

Then the condition changes to

result = myfunction()
if result is None:
  # error condition

Using None for no result available is very common in Python. Using
False for the same purpose (i.e. returning either a list or False)
is not. If you return False from a function, the only other possible
result should be True.

Regards,
Martin
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-05 Thread MRAB

On 05/12/2010 21:01, Martin v. Loewis wrote:

result = myfunction (vars)

if not result:
 # error condition

Now above I first realized that the function can also return an empty
list under some conditions and so changed it to


If your function returns a list when successful, it should not return
False in the error case. Instead, it should return None (indicating that
there is no list).

Then the condition changes to

result = myfunction()
if result is None:
   # error condition

Using None for no result available is very common in Python. Using
False for the same purpose (i.e. returning either a list or False)
is not. If you return False from a function, the only other possible
result should be True.


As an example, the re module uses both two approaches.

If you ask it to compile a regex:

rgx = re.compile(regex)

it either returns a PatternObject (if the regex is valid) or raises an
exception (if the regex isn't valid).

If you ask it to search a string:

rgx.search(string)

it returns either a MatchObject (if the match is successful) or None
(if the match isn't successful).
--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-04 Thread Steve Holden
On 12/2/2010 11:42 PM, Harishankar wrote:
 One of the reasons why I feared to do this is because I need to know each 
 and every exception that might be thrown by the function and litter my 
 top-level code with too many exception handlers.
 
You appear to be suffering from the delusion that all exceptions must be
caught and handled. This is far from being the case. But still, better
to have your top-level code littered with exception handlers than to
have your functions littered with if statements.

Quite often it's impossible for the function to know what needs to be
done when a specific conditions arises, in which case (presumably) you
have to return some error code and test for that ...

regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
PyCon 2011 Atlanta March 9-17   http://us.pycon.org/
See Python Video!   http://python.mirocommunity.org/
Holden Web LLC http://www.holdenweb.com/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-04 Thread Harishankar
 You appear to be suffering from the delusion that all exceptions must be
 caught and handled. This is far from being the case. But still, better
 to have your top-level code littered with exception handlers than to
 have your functions littered with if statements.

Of course not. But going by the replies here, it appears that Python has 
made exceptions as the norm for error handling which is ironical 
considering the meaning of the word exception. I find a bit cumbersome 
that exceptions are advocated for certain conditions which can be sanely 
worked around in the application's logic and even avoided, rather than 
waiting for them to get caught and providing an unsatisfactory result.

 
 Quite often it's impossible for the function to know what needs to be
 done when a specific conditions arises, in which case (presumably) you
 have to return some error code and test for that ...

Not necessarily. I wasn't talking about low-level or built-in exceptions. 
I was talking about using exceptions in my programming where often the 
function is reasonably confident of the kind of errors it is likely to 
incur. I did not start this as a criticism of Python's exceptions as 
such. I just expressed my personal aversion to using them in my own code.

However, in my next project I have started using exceptions and will keep 
an open mind on how it turns out. So far it doesn't seem too bad.


 
 regards
  Steve





-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-04 Thread D'Arcy J.M. Cain
On Sat, 4 Dec 2010 17:07:45 + (UTC)
Harishankar v.harishan...@gmail.com wrote:
 Of course not. But going by the replies here, it appears that Python has 
 made exceptions as the norm for error handling which is ironical 
 considering the meaning of the word exception. I find a bit cumbersome 
 that exceptions are advocated for certain conditions which can be sanely 
 worked around in the application's logic and even avoided, rather than 
 waiting for them to get caught and providing an unsatisfactory result.

It just seems to me that you have a semantic issue rather than a
technical one.  If the word exception was replaced by check or
something else would that make the process easier to swallow?

  try:
somefunc()
  check ValueError:
handle_error()

Whatever it's called it's just flow control.

  Quite often it's impossible for the function to know what needs to be
  done when a specific conditions arises, in which case (presumably) you
  have to return some error code and test for that ...
 
 Not necessarily. I wasn't talking about low-level or built-in exceptions. 
 I was talking about using exceptions in my programming where often the 
 function is reasonably confident of the kind of errors it is likely to 
 incur. I did not start this as a criticism of Python's exceptions as 
 such. I just expressed my personal aversion to using them in my own code.
 
 However, in my next project I have started using exceptions and will keep 
 an open mind on how it turns out. So far it doesn't seem too bad.

Open minds are good.

-- 
D'Arcy J.M. Cain da...@druid.net |  Democracy is three wolves
http://www.druid.net/darcy/|  and a sheep voting on
+1 416 425 1212 (DoD#0082)(eNTP)   |  what's for dinner.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-04 Thread Terry Reedy

On 12/4/2010 12:07 PM, Harishankar wrote:


Of course not. But going by the replies here, it appears that Python has
made exceptions as the norm for error handling which is ironical
considering the meaning of the word exception.


In communications parlance, 'exception' = out-of-band signal or return 
value, while 'return'ed value = in-band signal. A fake in-band return 
value, like returning None (ok) or False (worse) to *signal* 'I cannot 
return a list' is still an exception signal, even if 'in-band'.


The advantage of out-of-band signals is that they cannot be mistaken for 
valid in-band signals (return values). If a caller neglects to catch an 
exception, the process stops, as it should. If a caller neglects to 
check return values, the process goes on (at least for a while) under 
the pretense that error codes (in-band exception signals) are valid 
return values.


Neglecting to check return values for error codes is a common bug in C 
code. At worst, the process eventually return a bad value or performs a 
bad action. At best, it crashes sometime later, making the bug hard to find.


Or a function is called without even storing, let alone checking the 
return value. This is common for i/o functions. A program may 'finish' 
without any indication that it failed. If one does the same with Python 
functions (equally common), any exceptions *will* be passed up until 
either caught or displayed on the screen with an informative traceback 
(assuming that the screen is the not source of the error).


--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-04 Thread Steven D'Aprano
On Sat, 04 Dec 2010 17:07:45 +, Harishankar wrote:

 I find a bit cumbersome
 that exceptions are advocated for certain conditions which can be sanely
 worked around in the application's logic and even avoided, rather than
 waiting for them to get caught and providing an unsatisfactory result.

That's surprisingly rare in Python. In fact, I'd go so far as to say that 
in Python there is *nothing* that you can test for and then have a 
*guarantee* that it will succeed.

Of course, this is mainly of theoretical concern. In practice, Look 
Before You Leap (test first, then process) is often fine. But there are 
traps to look out for. For example, unless you are running a single-
process machine, the following code is subject to race conditions and is 
not safe:

if os.exists(pathname):
fp = open(pathname)
else:
handle_missing_file()

Just because the file is there when os.exists() looks for it, doesn't 
mean it still exists a microsecond later when you try opening it.

Or consider this code:

if y != 0:
result = x/y
else:
handle_division_by_zero()


This is also unsafe unless you know the type of y. Suppose y is an 
interval quantity that straddles zero, then division by y may fail even 
though y != 0.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-04 Thread Harishankar
On Sun, 05 Dec 2010 01:59:27 +, Steven D'Aprano wrote:

 Of course, this is mainly of theoretical concern. In practice, Look
 Before You Leap (test first, then process) is often fine. But there are
 traps to look out for. For example, unless you are running a single-
 process machine, the following code is subject to race conditions and is
 not safe:
 
 if os.exists(pathname):
 fp = open(pathname)
 else:
 handle_missing_file()
 
 Just because the file is there when os.exists() looks for it, doesn't
 mean it still exists a microsecond later when you try opening it.

I understand this line of thinking. And it makes sense to see why it 
would matter to leave the exception handling mechanism deal with such 
issues.

 
 Or consider this code:
 
 if y != 0:
 result = x/y
 else:
 handle_division_by_zero()
 
 
 This is also unsafe unless you know the type of y. Suppose y is an
 interval quantity that straddles zero, then division by y may fail even
 though y != 0.

Of course in each of these cases the in-built exceptions are used to 
verify the result of certain system level or lower level operations. My 
object was not to deprecate the system-level or other low level 
exceptions thrown by Python, but to consider whether such a mechanism 
would be a preferable method of handling your own programs error-
conditions. 

The issue to be considered by every programmer is to define what can be 
defined as the exceptional condition and what is a condition that merits 
merely different treatment without causing disruption of the normal flow 
of the program.

-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-04 Thread Tim Harig
On 2010-12-05, Harishankar v.harishan...@gmail.com wrote:
 Or consider this code:
 
 if y != 0:
 result = x/y
 else:
 handle_division_by_zero()
 
 
 This is also unsafe unless you know the type of y. Suppose y is an
 interval quantity that straddles zero, then division by y may fail even
 though y != 0.

 Of course in each of these cases the in-built exceptions are used to 
 verify the result of certain system level or lower level operations. My 
 object was not to deprecate the system-level or other low level 
 exceptions thrown by Python, but to consider whether such a mechanism 
 would be a preferable method of handling your own programs error-
 conditions. 

Whether you happen to like the exception mechanism and syntax or not, it is
the idiomatic way of handling errors in Python.  Using two different
conventions in your code will lead to confusion.  I come from a long C
background as well.  I have come to appreciate the power the Python's
exception handling provides.  It does everything that you need to do with
passing values in C and more.

 The issue to be considered by every programmer is to define what can be 
 defined as the exceptional condition and what is a condition that merits 
 merely different treatment without causing disruption of the normal flow 
 of the program.

That is an issue much harder to define.  Anything it is an obvious
error *should* throw an exception.  Invalid input is an error.
Unusable hardware states are errors.  Any invalid request to an object,
is an error.  Essentially anything that deviates from a normal flow of
a program, to handle an exceptional condition, is an error

Where it becomes less obvious is when you start using exceptions as
part normal control flow.  An example is a try it and see methodology.
You might for instance have a group of file objects which might or might
not support a particular method attribute.  You might have a preference for
using the attribute; but, have a fallback plan if it does not.  One way to
handle this is to try to use the attribute and catch the exception raised
if it is not present to execute your backup method.  I have found this
*essential* in some marsaling enviroments where you might not have access to
the meta-data of the object that you are working with.

Another, questionable but useful use, is to ignore the complex accounting
of your position inside of a complex data structure.  You can continue
moving through the structure until an exception is raised indicating
that you have reached a boundary of the structure.

Whether you accept uses of exceptions like these is more of a personal
quesion.  Like many good tools, they can be useful in ways that they were
never really designed to be and I would hate to proclude some of these
really useful features.

This can, of course, be easily abused.  I was once writing code, involving
complex object marshaling like I described above, with a partner who
wasn't totally familiar with Python.  We came to a situation where it
was impossible to know ahead of time what kind of object (one of two
possiblities) we would receive from another marshalled object and had no
meta-data to be able to figure out before attempting to access the object.
I used a try/except clause to resolve the problem.  The next day, I
found several poorly conceived try/except blocks in the codebase that
my partner had used for control structures using dictionaries because
he didn't know of dict.has_key().  I was not so pleased.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-04 Thread Tim Harig
On 2010-12-05, Tim Harig user...@ilthio.net wrote:
 Another, questionable but useful use, is to ignore the complex accounting
 of your position inside of a complex data structure.  You can continue
 moving through the structure until an exception is raised indicating
 that you have reached a boundary of the structure.

Here is another example in this vein.  A friend was trying to derive a
mathematical formula for determining the possibly distribution of results
from rolling arbitrariy numbers of m n-sided dice and needed several sets
of data in different directions from which to draw conclusions.

I created objects for dice and roles which contained and manipulated
multiple dice.  To generate a listing of all (non-uniq) possible roles,
I would call the first dices increment method read and read the dice
faces into a log until the first dice threw an exception that it could
not be further incremented.  Then I would call reset() on the first dice
and increment the second and so on much like the odometer of a car.

By using exceptions rather then checking the return value of increment,
the state information of the dice was completely isolated to the dice
and did not polute into the role structure; the logic for incrementing
the dice, logging the role state, and rolling over the dice where
all completely seperated and independent of any state; and therefore
reseting multiple previous dice as the higher values on the odometer were
incremented functioned automatically as each dice threw its own exception
recursively rather then requiring logic to handle these multiple rollovers.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-04 Thread Paul Rubin
Tim Harig user...@ilthio.net writes:
 A friend was trying to derive a mathematical formula for determining
 the possibly distribution of results from rolling arbitrariy numbers
 of m n-sided dice

http://en.wikipedia.org/wiki/Multinomial_distribution

 To generate a listing of all (non-uniq) possible roles, I would call
 the first dices increment method read and read the dice faces into a
 log until the first dice threw an exception that it could not be
 further incremented.  Then I would call reset() on the first dice and
 increment the second and so on much like the odometer of a car.

from itertools import product
m, n = 5, 2
for roll in product(*(xrange(1,m+1) for i in xrange(n))):
   print roll
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-04 Thread Steven D'Aprano
On Sun, 05 Dec 2010 04:13:02 +, Tim Harig wrote:

 Anything it is an obvious
 error *should* throw an exception.

Well, maybe... there are good use-cases for returning a sentinel. E.g. 
str.find, or the use of quiet NANs in IEEE floating point and decimal 
maths.

NANs and INFs in floating point maths are a good example of the right way 
to do it. If you forget to check for a NAN, it will propagate through 
your calculation. INF will, under some circumstances where it is 
mathematically valid to do so, will disappear leaving a normal result. 
This means you only need to check your result at the very end of the 
calculation, not after every step.

str.find is more troublesome, because the sentinel -1 doesn't propagate 
and is a common source of errors:

result = string[string.find(delim):]

will return a plausible-looking but incorrect result if delim is missing 
from string. But the convenience and familiarity of str.find means it 
will probably be around forever.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-04 Thread Tim Harig
On 2010-12-05, Paul Rubin no.em...@nospam.invalid wrote:
 Tim Harig user...@ilthio.net writes:
 A friend was trying to derive a mathematical formula for determining
 the possibly distribution of results from rolling arbitrariy numbers
 of m n-sided dice

 http://en.wikipedia.org/wiki/Multinomial_distribution

I sure he rediscovered much of that.  Working that out for himeself was
probably far more educational then simply reading an article on the
solution.

 To generate a listing of all (non-uniq) possible roles, I would call
 the first dices increment method read and read the dice faces into a
 log until the first dice threw an exception that it could not be
 further incremented.  Then I would call reset() on the first dice and
 increment the second and so on much like the odometer of a car.

 from itertools import product
 m, n = 5, 2
 for roll in product(*(xrange(1,m+1) for i in xrange(n))):
print roll

The fact that I bothered to create classes for the dice and roles, rather
then simply iterating over a list of numbers,  should tell you that I
produced was of a far more flexible nature; including the support for
roles with dice having different numbers of sides.  I basically created
a DSL that he could use to generate and automatically calculate the
properties of series of roles defined by one or more varying property.

I merely posted a simplied description of the dice-role objects because I
thought that it demonstrated how exceptions can provide eligance of control
for situations that don't involve what would traditionally be defined as an
error.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-03 Thread Tim Harig
On 2010-12-03, Paul Rubin no.em...@nospam.invalid wrote:
 Steven D'Aprano steve+comp.lang.pyt...@pearwood.info writes:
 There are better ways to handle errors than Python's exception system.
 I'm curious -- what ways would they be?
 I'm aware of three general exception handling techniques: ...
 What else is there?

 The Erlang approach is to chop the application into a lot of very
 lightweight processes, and let any process that encounters an error
 simply crash.  A monitoring process notices the crashed process and
 restarts it.  There is a supervision tree of uber-monitor processes
 that restart crashed monitor proceses.  I haven't programmed in that
 style myself and I'm not persuaded that it's better than what Python
 does, but I think it's different from the stuff on your list, which is

Erlang also offers an exception syntax almost identical to Python's for use
within a single process.

What makes Erlang's supervisor mode of error handling superior is that it
works for more then just the current vm.  If a process throws an exception,
the supervisor catches and handles it.  If a vm dies, a supervisor from
another vm takes over.  If an entire computer dies, a supervisor on another
computer takes over.  OTP provides some extremely advanced support for
supervisory structures.

 an answer to your what else is there.  I do know that they write some
 complex, very high reliability systems (phone switches) in Erlang.

Erlang isn't what I would call a very general purpose programming language
like Python; but, if you want to build highly scalable and/or highly
available systemes, there really isn't anything else that comes close
to it.  I am not really a huge fan of the purely functional nature of
the language; but, light weight processes using the actor model is the
way to go for concurrent processing.

The BEAM virtual machine is also a powerful system with its ability to
patch systems on the fly.  It has start to become the target for other
languages.  I know of two that are in current developement.  I wouldn't
mind seeing a version of Python that could leverage the power of the
BEAM vm.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-03 Thread Mel
Harishankar wrote:

 I think I understand the general trend of what you're saying. It
 definitely requires a mindset change. I still feel that user-defined
 exception classes might not be the way, but maybe I should allow the
 built-in exceptions which are thrown by library functions to follow its
 natural path upwards till it reaches the top level where it could be
 handled.

User-defined exception classes are no big deal, and I think they're helpful.  
At the minimum, they're just a few lines in a module, e.g.:

class SumpError (StandardError): '''Errors raised by the SUMP client.'''
class SumpIdError (SumpError): '''The wrong string was returned by an ID 
request.'''
class SumpFlagsError (SumpError): '''Illegal combination of flags.'''
class SumpStageError (SumpError): '''Illegal trigger stage setting.'''

This is from a module to drive some special hardware through a serial 
connection.  At this stage in development, I don't even have try/except 
statements for these.  It's enough that some typo will not silently put the 
hardware into an illegal state, and instead will report

Traceback (most recent call last):
  File logic_sniffer.py, line 184, in OnDeviceCapture
set_sump_options (grabber)
  File logic_sniffer.py, line 21, in set_sump_options
sump.set_flags (demux=True, filter=True, channel_groups=0x0, 
external=False, inverted=False) # only 1 channel group
  File /home/mwilson/sandbox/sump-analyzer/sump.py, line 160, in set_flags
raise SumpFlagsError
sump.SumpFlagsError

Because these are subclasses of StandardError, they'll be caught by any 
`except StandardError`, which may or may not turn out to be a mistake.

Once development is done, try/except for these will be in some window 
methods as part of a wxPython GUI, several call levels above the code that 
would raise the exceptions, up where a human user would take steps to change 
the way things are being done, or submit a bug report (more likely), or 
something.

 Maybe I should handle the error only at the highest level (UI level)
 rather than returning False to flag errors.
 
 One of the reasons why I feared to do this is because I need to know each
 and every exception that might be thrown by the function and litter my
 top-level code with too many exception handlers.

The advantage to the exceptions, is that they only need to be recognized and 
caught and handled at the UI level.  They don't have to be recognized and 
passed back up the call chain from level to level till they get to the right 
place -- the way out-of-band error returns have to be.

Mel.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-03 Thread Mark Wooding
Steven D'Aprano steve+comp.lang.pyt...@pearwood.info writes:

 On Thu, 02 Dec 2010 16:35:08 +, Mark Wooding wrote:
  There are better ways to handle errors than Python's exception system.

 I'm curious -- what ways would they be?

The most obvious improvement is resumable exceptions.

In general, recovering from an exceptional condition requires three
activities:

  * doing something about the condition so that the program can continue
running;

  * identifying some way of rejoining the program's main (unexceptional)
flow of control; and

  * actually performing that transfer, ensuring that any necessary
invariants are restored.

Python's `try ... finally' helps with the last; but Python intertwines
the first two, implementing both with `try ... except'.  The most
important consequence of this is that the logic which contains knowledge
about how to fix the condition must be closer to the code that
encountered the condition than the resume point is.  It's therefore hard
to factor out high-level policy about fixing conditions from the
relatively tedious business of providing safe points at which to resume
main execution.  (Effectively, each section of your program which wants
to avail itself of some high-level condition-fixing policy has to
provide its own protocol for expressing and implementing them.)

Phew.  That was abstract.  Can I come up with some examples?

I've been writing a (sort of) compiler recently.  When it encounters
errors, it reports a message to the user containing the position it had
reached in the source, updates a counter so that it can report a summary
at the end of the run and produce a sensible exit status, and then
attempts to carry on compiling as best it can.

The last bit -- attempting to carry on as best it can -- needs local
knowledge of what the compiler's doing and what actually went wrong.  If
the parser expected to find a delimiter, maybe it should pretend that it
found one, for example.

The other stuff, printing messages, updating counters, and so on, is all
done with some condition handlers wrapped around the meat of the
compiler.  That's written only once.  Everything that signals errors,
including standard I/O functions like open-a-file, gets the same
treatment.

(The remaining missing ingredient is a fluid variable which tracks the
current position in the source and is updated by the scanner; bits of
the compiler's semantic analysis machinery will temporarily focus
attention on other parts of the source using locations they saved during
the parse.  Implementing fluids in Python can be done with a context
manager: if you don't care about concurrency then you can use simple
variables; otherwise it's little fiddly and the syntax isn't very
comfortable, but it's still possible.)

A more familiar example, maybe, is the good old DOS `abort/retry/fail'
query.  Implementing such a thing in Python, as a general policy for
handling I/O errors, isn't possible.  Viewed narrowly, this is probably
a good thing: the old DOS query was very annoying.  But the difficulty
of implementing this policy illustrates the missing functionality.  And,
of course, if DOS had a proper resumable exception system, programs
could have overridden the annoying query.

In general, the code which discovers an exceptional condition may have
several options for how to resume.  It might be possible to ignore the
situation entirely and carry on regardless (`false alarm!').  It might
be possible to try again (`transient failure').  Alas, the logic which
is capable of implementing these options is usually too low-level and
too close to the action to be able to decide among them sensibly.
(Maybe a human user should be consulted -- but that can drag in user
interface baggage into a low-level networking library or whatever.)
Resumable exceptions provide a way out of this mess by separating the
mechanics of resumption from policy of which resumption option to
choose.

It's easy to show that a resumable exception system can do everything
that a nonresumable system (like Python's) can do (simply put all of the
recovery logic at the resume point); but the converse is not true.

There are some other fringe benefits to resumable exceptions.

  * It's usual to report a stack backtrace or similar if an exception
occurs but nothing manages to resume execution.  If unwinding the
stack is intertwined with working out how to resume execution, then
whenever you /try/ to run an applicable handler, you have to reify
the stack context and stash it somewhere in case the handler doesn't
complete the job.  This makes raising exceptions more expensive than
they need to be.

  * You can use the same mechanism for other kinds of communication with
surrounding context.  For example, Python occasionally emits
`warnings', which have their own rather simple management system
(using global state, so it's hard to say `don't issue MumbleWarnings
while we frob the widgets' in a 

Re: Comparison with False - something I don't understand

2010-12-03 Thread Harishankar
On Fri, 03 Dec 2010 14:31:43 +, Mark Wooding wrote:

 The most obvious improvement is resumable exceptions.

This is probably what I had in mind but I just couldn't explain it the 
way you did below.

 
 In general, recovering from an exceptional condition requires three
 activities:
 
   * doing something about the condition so that the program can continue
 running;
 
   * identifying some way of rejoining the program's main (unexceptional)
 flow of control; and
 
   * actually performing that transfer, ensuring that any necessary
 invariants are restored.

This really sums up my thoughts about exceptions better than I could have 
explained! I just felt instinctively that I had missed something, but it 
appears to be a break in logic of the code somewhere which I thought was 
my fault. Seems that exception handling requires a lot of forethought 
since the control of program execution breaks at the point of exception 
with no obvious way to rejoin it seamlessly whereas with an error, a 
simple if condition could handle the error state and resume execution 
from that point forward. This is the main reason why I think I used 
simple error codes to handle certain recoverable conditions and avoided 
exceptions.   

I quite enjoyed your post. Thank you for explaining a lot of issues which 
I probably could not have figured out on my own.
-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-03 Thread Harishankar
On Thu, 02 Dec 2010 17:33:47 -0800, Aahz wrote:

 Please demonstrate that using ``if`` blocks for True/False is impler and
 cleaner than using ``try`` blocks to handle exceptions.

It is my personal preference and coding style for certain situations I 
encounter in my own programs and not something that I could prove to 
anybody else by theory.

But anyway, in certain circumstances, exceptions create a break in flow 
of the execution of a program that makes it non-obvious as to how to 
resume flow at the point of disruption especially when the exception 
handling mechanism is at a higher level. While an error flag can simply 
set an alarm and allow other code to continue and allow the calling 
higher-level code to handle the alarm/flag as it sees fit.


-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-03 Thread Emile van Sebille

On 12/3/2010 6:31 AM Mark Wooding said...


It's easy to show that a resumable exception system can do everything
that a nonresumable system (like Python's) can do (simply put all of the
recovery logic at the resume point); but the converse is not true.

There are some other fringe benefits to resumable exceptions.


I do a lot of work in a variant of Business Basic that has always 
offered resumable exceptions.  The closest I get in python is using 
import pdb;pdb.set_trace().  I wonder what it would take to allow for 
any exceptions occurring outside a try/except context to dump the 
traceback, then invoke pdb.set_trace() before bailing to allow for both 
investigation and possible recovery and continuance?


Emile



--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-03 Thread Aahz
In article mailman.187.1291397553.2649.python-l...@python.org,
Harishankar  v.harishan...@gmail.com wrote:
On Thu, 02 Dec 2010 17:33:47 -0800, Aahz wrote:

 Please demonstrate that using ``if`` blocks for True/False is impler and
 cleaner than using ``try`` blocks to handle exceptions.

It is my personal preference and coding style for certain situations I 
encounter in my own programs and not something that I could prove to 
anybody else by theory.

Note carefully that I said demonstrate, not prove.  If using ``if``
is so clearly better in some situations, you should be able to provide an
example.
-- 
Aahz (a...@pythoncraft.com)   * http://www.pythoncraft.com/

Think of it as evolution in action.  --Tony Rand
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-03 Thread alex23
On Dec 3, 2:12 am, Tim Harig user...@ilthio.net wrote:
 Actually, I thought that debate was resolved years ago.  I cannot think of
 a single recently developed programming language that does not provide
 exception handling mechanisms because they have been proven more reliable.

Google's Go lacks exceptions and I believe that was a deliberate
design choice.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-03 Thread Tim Harig
On 2010-12-04, alex23 wuwe...@gmail.com wrote:
 On Dec 3, 2:12 am, Tim Harig user...@ilthio.net wrote:
 Actually, I thought that debate was resolved years ago.  I cannot think of
 a single recently developed programming language that does not provide
 exception handling mechanisms because they have been proven more reliable.

 Google's Go lacks exceptions and I believe that was a deliberate
 design choice.

1. The debate that I was referring to was between simple function checking
vs. everything else.  I didn't mean to automatically proclude any
newer methodologies of which I might not even be aware.

2.  I would consider the defer/panic/recovery mechanism functionally similar 
to exceptions in most ways.  It allows the error handling
code to be placed at a higher level and panics tranverse the stack
until they are handled by a recovery.  This is basically equivilent
to how exceptions work using different names.  The change is basically 
the defer
function which solves the problem of any cleanup work that the
function needs to do before the panic is raised.  I like it, its
nice.  It formalizes the pattern of cleaning up within an exception
block and re-raising the exception.

I do have to wonder what patterns will emerge in the object given
to panic().  Since it takes anything, and since Go doesn't have an
object hierarchy, much less an exception hierarchy, the panic value
raised may or may not contain the kind of detailed information that
can be obtained about the error that we are able to get from the
Exception objects in Python.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-03 Thread Tim Harig
On 2010-12-03, Harishankar v.harishan...@gmail.com wrote:
 On Fri, 03 Dec 2010 14:31:43 +, Mark Wooding wrote:
 In general, recovering from an exceptional condition requires three
 activities:
 
   * doing something about the condition so that the program can continue
 running;
 
   * identifying some way of rejoining the program's main (unexceptional)
 flow of control; and
 
   * actually performing that transfer, ensuring that any necessary
 invariants are restored.

 my fault. Seems that exception handling requires a lot of forethought 
 since the control of program execution breaks at the point of exception 
 with no obvious way to rejoin it seamlessly whereas with an error, a 
 simple if condition could handle the error state and resume execution 
 from that point forward. This is the main reason why I think I used 
 simple error codes to handle certain recoverable conditions and avoided 
 exceptions.   

If you are returning an error code to the above function, then there is
nothing that you cannot do with with the exception.  Basically, you resolve
the issue in your except block just as you would in the block of your if
statement after returning the error code.  If you try and fail to handle
the exception or just needed to do some cleanup before allowing the
exception to continue, then you just re-raise the exception. 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Alice Bevan–McGregor

Howdy!


When I run pychecker through my modules I get the message that
comparisons with False is not necessary and that it might yield
unexpected results.


Comparisons against False -are- dangerous, demonstrated below.

Yet in some situations I need to specifically check whether False was 
returned or None was returned. Why is comparison with False so bad?


(False == 0) is True
(True == 1) is True

The bool type is a subclass of int!  (Run those lines in a Python 
interpreter to see.  ;)



if var == False:


if var is False: …

So how do you get around this? My functions return False and None under 
different circumstances. Should I raise exceptions instead? I feel it's 
unnecessary clutter to use exceptions unless absolutely no other 
solution is available and yet I have doubts about the False value.


If you want to check not just for value equivelance (False == 0) but 
literal type, use the is comparator.  is checks, and others correct 
me if I'm wrong, the literal memory address of an object against 
another.  E.g. False, being a singleton, will always have the same 
memory address.  (This is true of CPython, possibly not of Python 
implementations like Jython or IronPython.)  Using is will be 
effective for checking for literal None as well.


When ever I need to test for None, I always use the is comparator.  
It's also more English-like.  (None, evaluating to False when using 
'==', is useful when all you care about is having a blank default 
value, for example.)


— Alice.



--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Nobody
On Thu, 02 Dec 2010 07:28:30 +, Harishankar wrote:

 When I run pychecker through my modules I get the message that 
 comparisons with False is not necessary and that it might yield 
 unexpected results.
 
 Yet in some situations I need to specifically check whether False was 
 returned or None was returned. Why is comparison with False so bad?

The behaviour may be counterintuitive.

One might expect that x == False is equivalent to not x. Sometimes it
is, sometimes it isn't.

E.g. 0 and 0.0 are equal to False and are equivalent to False when
converted to booleans:

 0 == False
True
 not 0
True

 0.0 == False
True
 not 0.0
True

[],  and None aren't equal to False but are equivalent to False when
converted to booleans:

 [] == False
False
 not []
True

  == False
False
 not 
True

 None == False
False
 not None
True

The boolean conversions are what's relevant for if x ..., while x ...,
etc.

If you want to test specifically for True, False or None, use is rather
than an equality check. This eliminates the warning and doesn't
risk misleading someone reading the code.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Harishankar
On Thu, 02 Dec 2010 00:15:42 -0800, Alice Bevan–McGregor wrote:

 Howdy!

Good day to you! 

 (False == 0) is True
 (True == 1) is True

I see. Thanks for this. I suspected this, but wasn't sure.

 The bool type is a subclass of int!  (Run those lines in a Python
 interpreter to see.  ;)
 
 if var == False:
 
 if var is False: …

So var is False is safer to use when I want to specifically check 
whether var is set to False and not 0 or None?

 If you want to check not just for value equivelance (False == 0) but
 literal type, use the is comparator.  is checks, and others correct
 me if I'm wrong, the literal memory address of an object against
 another.  E.g. False, being a singleton, will always have the same
 memory address.  (This is true of CPython, possibly not of Python
 implementations like Jython or IronPython.)  Using is will be
 effective for checking for literal None as well.

Thanks, it makes sense to me now. Literal equivalence is what I was 
looking for. I didn't quite understand whether == achieved this or not. 
Now I guess I know. 

 
 When ever I need to test for None, I always use the is comparator.
 It's also more English-like.  (None, evaluating to False when using
 '==', is useful when all you care about is having a blank default value,
 for example.)

Yes, but in my function I don't want to confuse False with 0 or anything 
else except False. Thanks again for explaining this clearly.
-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Harishankar
On Thu, 02 Dec 2010 09:58:18 +, Nobody wrote:
 If you want to test specifically for True, False or None, use is
 rather than an equality check. This eliminates the warning and doesn't
 risk misleading someone reading the code.

Thanks so much for this very specific answer. I guess is is what I am 
looking for. :-)

-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Stephen Hansen
On 12/2/10 2:02 AM, Harishankar wrote:
 On Thu, 02 Dec 2010 00:15:42 -0800, Alice Bevan–McGregor wrote:
 The bool type is a subclass of int!  (Run those lines in a Python
 interpreter to see.  ;)

 if var == False:

 if var is False: …
 
 So var is False is safer to use when I want to specifically check 
 whether var is set to False and not 0 or None?

Equality is a somewhat fuzzy concept.

By convention and habit, its usually fine and clear: but its still fuzzy
and up to each individual object involved to answer the question of
equality.

Now, its generally suggested in Python to do fairly vague truth testing:
if x and if not x as opposed to concepts like if x == True and if
x == False because the former is broad but usually more correct, and
the latter can lead to some unexpected semantics.

But that doesn't mean you must never check if something is False or
True: there are times when you really do want or need to see if _False_
is what's being returned, or _True_, or _None_. In this case, use is,
yes, indeed.

The is operator checks absolute object identity, and so is how you
should do that check in cases where you want to test the distinction
between Is it /False/, or just something false-ish or not-true or
nothing-ish?

Generally speaking in Python, you usually want to do tests as if x or
if not x.

But sometimes you need to know if x is a specific singleton value:
True, False or None. In that case, its okay to do if x is True, if x
is False or if x is None.

But you should only do that after the simple test is deemed
inappropriate in your API or situation.

And-- here's the rub-- while is is absolutely OK and right for you to
use to test if an object is one of those singletons, its *probably* NOT
what you want to do in any other situation*.

Outside of the True/False/None singletons, and places where you're doing
some special OOP-stuff, you almost certainly don't want to use 'is', but
use equality checking (even if its fuzzy, because its fuzzy) instead.

This demonstrates why is should be avoided except when in those
singleton situations (except when you need to, of course):

 a = 2
 b = 2
 a is b
True
 a == b
True
 a = 2
 b = 2
 a is b
False
 a == b
True

(If you're wondering why that's happening: Python makes very little in
the way of promises with regard to object identity. It may choose to
make a whole new int object of value 2 every time you type 2, or use the
same old int object each time: sure, presently it tends to only share
small integers for re-use, but that's not a promise, not a documented
feature, but a function of the current implementation. It could happen
tomorrow, in theory, that where a = 1; b = 1; become the same
object as far as is is concerned even though today they are
different... is should only be used in situations where you care about
absolute object identity, not *value*.)
--

   Stephen Hansen
   ... Also: Ixokai
   ... Mail: me+list/python (AT) ixokai (DOT) io
   ... Blog: http://meh.ixokai.io/

* P.S. I'm not saying its never right to use is outside of The
Singletons. Just that its probably not, for most people, what they
actually should do in most code. There are numerous counter-examples, of
course. Its just a general guideline to follow. Until a need arises that
demonstrates otherwise.



signature.asc
Description: OpenPGP digital signature
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Ben Finney
Harishankar v.harishan...@gmail.com writes:

 When I run pychecker through my modules I get the message that
 comparisons with False is not necessary and that it might yield
 unexpected results.

Good advice.

 Yet in some situations I need to specifically check whether False was
 returned or None was returned. Why is comparison with False so bad?

Because it's almost always unnecessary and can yield unexpected results
:-)

In other words, the only purpose of the ‘bool’ type is to have values
explicitly designed for testing in Boolean conditions. Comparing them to
the literals is a code smell — indicating a poor design.

 # example code which matches both False and None
 if not var:
 # do something

Can you give a specific real-world example of why this is not good
enough? It's likely we can suggest better ways of achieving the broader
purpose.

 So how do you get around this? My functions return False and None
 under different circumstances.

Usually it is None that will be the special case, so it's usually better
to write something like::

result = foo()

if result is None:
# do special things

But that's just one possibility, and might not apply in your use case.

 Should I raise exceptions instead? I feel it's unnecessary clutter to
 use exceptions unless absolutely no other solution is available and
 yet I have doubts about the False value.

More details of the problem you're trying to solve would help with
giving specific advice.

-- 
 \ “I was sad because I had no shoes, until I met a man who had no |
  `\   feet. So I said, ‘Got any shoes you're not using?’” —Steven |
_o__)   Wright |
Ben Finney
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Harishankar
On Thu, 02 Dec 2010 22:19:25 +1100, Ben Finney wrote:

 More details of the problem you're trying to solve would help with
 giving specific advice.

I'm writing functions with multiple points of failure exits. I use return 
False as a way to flag the error condition rather than raising 
exceptions. But under certain circumstances, the function can also return 
empty lists which equate to false when using the condition like:

# myfunction () can return a list of tuples, but can also return an empty
# list under certain conditions since it's query a database and the result
# can be empty also

result = myfunction (vars) 

if not result:
# error condition

Now above I first realized that the function can also return an empty 
list under some conditions and so changed it to

if result == False:
# error condition


But now I realize that it's better to use is

if result is False:
# error condition

That is how my problem arose.

- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Harishankar
On Thu, 02 Dec 2010 02:49:50 -0800, Stephen Hansen wrote:
...
...
...
 * P.S. I'm not saying its never right to use is outside of The
 Singletons. Just that its probably not, for most people, what they
 actually should do in most code. There are numerous counter-examples, of
 course. Its just a general guideline to follow. Until a need arises that
 demonstrates otherwise.

Here I'm using it to compare the result of a function where I 
specifically return False on error condition, so I think it's better I 
check it against the literal False rather than the fuzzy False produced 
by the boolean operation.

I wouldn't do this in most situations though, but I did need to 
distinguish between the the empty list and False and using the broader 
form as in if not a did not work as expected.

-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Tim Chase

On 12/02/2010 08:18 AM, Harishankar wrote:

Here I'm using it to compare the result of a function where I
specifically return False on error condition,


This sounds exactly like the reason to use exceptions...you have 
an exceptional error condition.


-tkc


--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Harishankar
On Thu, 02 Dec 2010 08:44:11 -0600, Tim Chase wrote:

 On 12/02/2010 08:18 AM, Harishankar wrote:
 Here I'm using it to compare the result of a function where I
 specifically return False on error condition,
 
 This sounds exactly like the reason to use exceptions...you have an
 exceptional error condition.
 
 -tkc

There are some reasons why I hate exceptions but that is a different 
topic. However, in short I can say that personally:

1. I hate try blocks which add complexity to the code when none is 
needed. Try blocks make code much more unreadable in my view and I use it 
only for the built-in exceptions when absolutely needed.

2. I prefer the less irksome True or False to do error checking. 
Exceptions seem too heavyweight for simple problems.

3. Philosophically I think exception handling is the wrong approach to 
error management. I have never grown up programming with exceptions in C 
and I couldn't pick up the habit with python either. Did I mention that I 
detest try blocks? try blocks seem ugly and destroy code clarity at least 
in my view. And enclosing single statements under separate try blocks 
seem to add a lot of clutter. 

-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Steve Holden
On 12/2/2010 9:13 AM, Harishankar wrote:
 On Thu, 02 Dec 2010 22:19:25 +1100, Ben Finney wrote:
 
 More details of the problem you're trying to solve would help with
 giving specific advice.
 
 I'm writing functions with multiple points of failure exits. I use return 
 False as a way to flag the error condition rather than raising 
 exceptions. But under certain circumstances, the function can also return 
 empty lists which equate to false when using the condition like:
 
 # myfunction () can return a list of tuples, but can also return an empty
 # list under certain conditions since it's query a database and the result
 # can be empty also
 
 result = myfunction (vars) 
 
 if not result:
 # error condition
 
 Now above I first realized that the function can also return an empty 
 list under some conditions and so changed it to
 
 if result == False:
 # error condition
 
 
 But now I realize that it's better to use is
 
 if result is False:
 # error condition
 
 That is how my problem arose.
 
Did you think about using exceptions to handle exceptional conditions?
If you are new to Python it may not be the obvious soltuion, but it can
greatly simplify program logic.

regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
PyCon 2011 Atlanta March 9-17   http://us.pycon.org/
See Python Video!   http://python.mirocommunity.org/
Holden Web LLC http://www.holdenweb.com/

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Steve Holden
On 12/2/2010 9:56 AM, Harishankar wrote:
 3. Philosophically I think exception handling is the wrong approach to 
 error management. I have never grown up programming with exceptions in C 
 and I couldn't pick up the habit with python either. Did I mention that I 
 detest try blocks? try blocks seem ugly and destroy code clarity at least 
 in my view. And enclosing single statements under separate try blocks 
 seem to add a lot of clutter. 

Whereas lots of nested if statements to test that multiple errors have
all not occurred is a model of clarity? This sounds to me like a
prejudice that will harm your Python development.

regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
PyCon 2011 Atlanta March 9-17   http://us.pycon.org/
See Python Video!   http://python.mirocommunity.org/
Holden Web LLC http://www.holdenweb.com/

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Tim Harig
On 2010-12-02, Harishankar v.harishan...@gmail.com wrote:
 There are some reasons why I hate exceptions but that is a different 
 topic. However, in short I can say that personally:

 1. I hate try blocks which add complexity to the code when none is 
 needed. Try blocks make code much more unreadable in my view and I use it 
 only for the built-in exceptions when absolutely needed.

Actually, exceptions remove a ton of complexity and almost universally
remove a ton of redundant error checking code.  Second, they aleviate a
ton of design complexity about designing a clean and unified method of
error handling throughout the program.  Using exceptions, the only real
questions are where to handle various errors.  It is a godsend for having
to clean up intermediary results when an error occurs as part of a complex
set of dependant sequential operations.

 2. I prefer the less irksome True or False to do error checking. 
 Exceptions seem too heavyweight for simple problems.

Error handling in C huge source of bugs.  First, error handling code is
scattered throughout the codebase and second it is hard to test the error
handling code for a number of failures.  Being able to raise exceptions
within your test code makes it much easier to write tests capable of
detecting error handling bugs.

 3. Philosophically I think exception handling is the wrong approach to 
 error management. I have never grown up programming with exceptions in C 
 and I couldn't pick up the habit with python either. Did I mention that I 
 detest try blocks? try blocks seem ugly and destroy code clarity at least 
 in my view. And enclosing single statements under separate try blocks 
 seem to add a lot of clutter. 

Perhaps you should take a look at how Erlang appoaches exception handling.
Being message passing and concurrency oriented, Erlang encourages ignoring
error conditions within worker processes.  Errors instead cause the worker
processes to be killed and a supervisory process is notified, by message,
so that it can handle the error and respawn the worker process.  Since it
doesn't use try/exept blocks, maybe that will be more to your liking.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Harishankar
On Thu, 02 Dec 2010 10:19:35 -0500, Steve Holden wrote:

 On 12/2/2010 9:13 AM, Harishankar wrote:
 On Thu, 02 Dec 2010 22:19:25 +1100, Ben Finney wrote:
 
 More details of the problem you're trying to solve would help with
 giving specific advice.
 
 I'm writing functions with multiple points of failure exits. I use
 return False as a way to flag the error condition rather than raising
 exceptions. But under certain circumstances, the function can also
 return empty lists which equate to false when using the condition like:
 
 # myfunction () can return a list of tuples, but can also return an
 empty # list under certain conditions since it's query a database and
 the result # can be empty also
 
 result = myfunction (vars)
 
 if not result:
 # error condition
 
 Now above I first realized that the function can also return an empty
 list under some conditions and so changed it to
 
 if result == False:
 # error condition
 
 
 But now I realize that it's better to use is
 
 if result is False:
 # error condition
 
 That is how my problem arose.
 
 Did you think about using exceptions to handle exceptional conditions?
 If you are new to Python it may not be the obvious soltuion, but it can
 greatly simplify program logic.
 
 regards
  Steve

I am not new to Python but I am not a fan of exceptions either. I prefer 
to avoid writing my own exceptions because it feels too heavy and clunky 
for simple error checking. Most times I find simple error checking ample 
for my purposes.

Of course, I use the built-in exception objects when I have no choice, 
but I hate try blocks. They add clunkiness to code and besides exception 
objects seem to be fairly heavy-duty for simple error conditions where a 
true/false flag would probably suffice.

I am also wary of using larger catch-all try blocks or try blocks with 
multiple exception exits (which seem to make tracking subtle bugs 
harder). I prefer the philosophy of dealing with errors immediately as 
they arise, rather than delegate them to exception mechanism. Of course, 
I could wrap single statements in try blocks, but that makes the code 
even messier without any significant benefits.

-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Grant Edwards
On 2010-12-02, Steve Holden st...@holdenweb.com wrote:
 On 12/2/2010 9:13 AM, Harishankar wrote:
 
 if not result:
 # error condition
 
 Now above I first realized that the function can also return an empty 
 list under some conditions and so changed it to
 
 if result == False:
 # error condition
 
 
 But now I realize that it's better to use is
 
 if result is False:
 # error condition
 
 That is how my problem arose.

 Did you think about using exceptions to handle exceptional conditions?
 If you are new to Python it may not be the obvious soltuion, but it can
 greatly simplify program logic.

If you're not used to using exceptions it may at first seem like they
take extra effort to use.  But usually, in the end, they end up being
less work (and more importantly easier to read and less bugs).

-- 
Grant Edwards   grant.b.edwardsYow! He is the MELBA-BEING
  at   ... the ANGEL CAKE
  gmail.com... XEROX him ... XEROX
   him --
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Stephen Hansen
On 12/2/10 6:56 AM, Harishankar wrote:
 On Thu, 02 Dec 2010 08:44:11 -0600, Tim Chase wrote:
 
 On 12/02/2010 08:18 AM, Harishankar wrote:
 Here I'm using it to compare the result of a function where I
 specifically return False on error condition,

 This sounds exactly like the reason to use exceptions...you have an
 exceptional error condition.

 -tkc
 
 There are some reasons why I hate exceptions but that is a different 
 topic. However, in short I can say that personally:

To each his/her own, of course; but --

 3. Philosophically I think exception handling is the wrong approach to 
 error management. 

Exceptions aren't about error management; they are about exceptional
conditions: some are errors, others are entirely normal situations you
know are going to happen (such as reaching the end of a sequence as you
iterate over it: that's not an error, but it is special). To be
philosophically opposed to them seems to me to be philosophically in
favor of race conditions.

 I have never grown up programming with exceptions in C 
 and I couldn't pick up the habit with python either. Did I mention that I 
 detest try blocks? try blocks seem ugly and destroy code clarity at least 
 in my view. And enclosing single statements under separate try blocks 
 seem to add a lot of clutter. 

? How do they destroy clarity or add clutter, since presumably you have
to deal with that False in some way with logical structure -- which
always does whitespace in Python. If not immediately, then up the call
stack (which seems to imply you should just not use a try/except and let
the exception unwind the stack to wherever in your code someone wants to
deal with it).

if is_correct():
result = do_thing()
else:
do_error_handling()

try:
result = do_thing()
except KeyError:
do_error_handling()

And as an aside, the more statements one puts into a try/except block:
and the more complicated a statement at that-- the more likely it is
they are going to mess up and do something Wrong.

Now, all that said: sure, in some situations I do prefer the check
first style of programming where exceptions don't end up being used.
Its not *wrong* to return False on an error condition: its going
against the grain, though, and makes your code harder to deal with
long-term if only because now there's two separate mechanisms that
errors happen in it.

You can't totally do away with exceptions in Python, even if you try
very hard. So with that in mind, IMHO, the best approach is to just...
get over it, and learn to appreciate them :)

But, to each his or her own. :)

--

   Stephen Hansen
   ... Also: Ixokai
   ... Mail: me+list/python (AT) ixokai (DOT) io
   ... Blog: http://meh.ixokai.io/



signature.asc
Description: OpenPGP digital signature
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Harishankar
On Thu, 02 Dec 2010 15:25:55 +, Tim Harig wrote:

...
...
 
 Perhaps you should take a look at how Erlang appoaches exception
 handling. Being message passing and concurrency oriented, Erlang
 encourages ignoring error conditions within worker processes.  Errors
 instead cause the worker processes to be killed and a supervisory
 process is notified, by message, so that it can handle the error and
 respawn the worker process.  Since it doesn't use try/exept blocks,
 maybe that will be more to your liking.

Thanks for the reply.

I understand that the error vs exception debate is quite a big one in the 
programming community as a whole and I don't consider myself very 
knowledgeable in these issues. However, I will try to approach this with 
an open mind and see whether I can work with exceptions comfortably in 
Python. I do understand both sides of the issue. Exceptions seem to be 
generally more reliable but I feel they add a lot of complexity 
particular when a lot of code is placed in a try block. 

-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Tim Harig
On 2010-12-02, Harishankar v.harishan...@gmail.com wrote:
 I am also wary of using larger catch-all try blocks or try blocks with 
 multiple exception exits (which seem to make tracking subtle bugs 
 harder). I prefer the philosophy of dealing with errors immediately as 

If you are using exceptions to try to catch bug then you are using them
improperly.  Exceptions (with the exception (no pun intended) of
AssertionError) are designed to catch error conditions, not bugs.

 harder). I prefer the philosophy of dealing with errors immediately as 
 they arise, rather than delegate them to exception mechanism. Of course, 
 I could wrap single statements in try blocks, but that makes the code 
 even messier without any significant benefits.

Actually, finer grained error handling commonly covers up bugs.  If you
want to find bugs, you want to make the program prone to crashing if
a bug is present.  It is all too easy to accidently mistake the return
value of a function as error condition and handle it rather the letting
the program crash.  By separating the results from the transmission of
error conditions (in effect taking error conditions out of band) then
you make it much harder to make such a mistake because you have to
explicity indicate which error conditions your code is capable of
generating.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Harishankar
On Thu, 02 Dec 2010 07:35:18 -0800, Stephen Hansen wrote:

 Exceptions aren't about error management; they are about exceptional
 conditions: some are errors, others are entirely normal situations you
 know are going to happen (such as reaching the end of a sequence as you
 iterate over it: that's not an error, but it is special). To be
 philosophically opposed to them seems to me to be philosophically in
 favor of race conditions.

Maybe I worded that part wrongly. Of course I get that error handling is 
only a part of exception mechanism. I agree that the built-in exceptions 
are useful but I prefer most times not to catch them. :-)

 ? How do they destroy clarity or add clutter, since presumably you have
 to deal with that False in some way with logical structure -- which
 always does whitespace in Python. If not immediately, then up the call
 stack (which seems to imply you should just not use a try/except and let
 the exception unwind the stack to wherever in your code someone wants to
 deal with it).

The reason why I said they remove clarity is because it's not always 
obvious at which point the exception may be raised. In other words, 
within a try block there may be multiple statements that generate the 
exception. Of course, as I said before, one way would be to wrap single 
statements with the try block and avoid this issue.

 
 if is_correct():
 result = do_thing()
 else:
 do_error_handling()
 
 try:
 result = do_thing()
 except KeyError:
 do_error_handling()

Of course, to me the if statement would make more sense because I 
immediately figure out the exact condition being tested against while the 
exception object is not always so clear and maybe ambiguous in some 
cases. 

Also if that same type of exception is raised by another statement within 
a function that is called within the try block then it would be handled 
by the same except block right? This is where it gets a bit confusing to 
me and the flow of code is not always obvious. That's why I prefer atomic 
error handling where I know exactly which part of the code led to the 
result.

 And as an aside, the more statements one puts into a try/except block:
 and the more complicated a statement at that-- the more likely it is
 they are going to mess up and do something Wrong.
 
 Now, all that said: sure, in some situations I do prefer the check
 first style of programming where exceptions don't end up being used.
 Its not *wrong* to return False on an error condition: its going
 against the grain, though, and makes your code harder to deal with
 long-term if only because now there's two separate mechanisms that
 errors happen in it.

I realize that it is impossible for me to avoid exception mechanism 
myself. So I restrict it only to situations where I cannot avoid it (e.g. 
inbuilt exceptions in some cases where I want to handle it myself)


 
 You can't totally do away with exceptions in Python, even if you try
 very hard. So with that in mind, IMHO, the best approach is to just...
 get over it, and learn to appreciate them :)

Finding it hard to appreciate exceptions myself. But I am used to 
thinking linearly. A piece of code which does not explain itself in the 
most obvious way even if I wrote it always worries me.

-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Tim Harig
On 2010-12-02, Harishankar v.harishan...@gmail.com wrote:
 I understand that the error vs exception debate is quite a big one in the 
 programming community as a whole and I don't consider myself very 

Actually, I thought that debate was resolved years ago.  I cannot think of
a single recently developed programming language that does not provide
exception handling mechanisms because they have been proven more reliable.

 Python. I do understand both sides of the issue. Exceptions seem to be 
 generally more reliable but I feel they add a lot of complexity 
 particular when a lot of code is placed in a try block. 

Lines of code is one measure of complexity.  Each line of code has a small
chance of containing a bug.  The more lines of code that you have, then the
more likely that one of them contains a bug.  Exceptions, by placing error
handling code in fewer places, requires much fewer lines of code then
requiring error handling code after each call that might produce an error
condition.

The operations of propogating an error up to the higher level logic of
the program is another measure.  In languages without exception handling,
careful planning is needed to pass error conditions up through the call
stack until they reach a high enough level in the logic that decisions
can be made about how to handle them.  Even further planning must be
taken so that when the error condition reaches level where it needs to
be handled, that enough information about the error is present to know
exactly what went wrong so that it can figure out what to do about it.
This usually involves using globals like errorno to pass out of band
information about the error.  Sometimes you even need to know about how
the error affect intermediate levels, did the intermediate code attempt
to handle the condtion and fail?  The Openssl error handling system,
that creates an error logging chain is an example of just how complex
this can become.  You gain all of this functionality automatically
through exception mechanisms; without all of the complexity.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Harishankar
On Thu, 02 Dec 2010 15:53:49 +, Tim Harig wrote:

 If you are using exceptions to try to catch bug then you are using them
 improperly.  Exceptions (with the exception (no pun intended) of
 AssertionError) are designed to catch error conditions, not bugs.

I agree. But more specifically some exceptions seem too broad to catch 
specific errors that occur in MY code rather than in a system call or a 
library call. 

Also writing my own exception objects and raising exceptions seem to add 
too much of complexity to what is essentially a simple problem. This is 
what I was trying to explain.

 Actually, finer grained error handling commonly covers up bugs.  If you
 want to find bugs, you want to make the program prone to crashing if a
 bug is present.  It is all too easy to accidently mistake the return
 value of a function as error condition and handle it rather the letting
 the program crash.  By separating the results from the transmission of
 error conditions (in effect taking error conditions out of band) then
 you make it much harder to make such a mistake because you have to
 explicity indicate which error conditions your code is capable of
 generating.

Doesn't the same finer grained exception mechanism make it prone to the 
same problems? 

Actually return values of functions which I write myself can be as 
specific and to the point. I could make it as fuzzy or as precise as I 
like. This is no doubt, something that I could emulate with an exception 
as well, but only make it slightly more complex with no obvious benefit.

As I said before, the way exceptions are caught seem to me to be the most 
confusing bit. Non-atomic operations always worry me. What if my function 
which is wrapped inside a try block has two different statements that 
raised the same exception but for different reasons? With error handling 
I could probably handle it right below the statement which was called and 
thus reduce the problem???

-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Mark Wooding
Harishankar v.harishan...@gmail.com writes:

 There are some reasons why I hate exceptions but that is a different 
 topic. However, in short I can say that personally:

 1. I hate try blocks which add complexity to the code when none is 
 needed. Try blocks make code much more unreadable in my view and I use it 
 only for the built-in exceptions when absolutely needed.

Very little code actually needs `try' blocks.

 2. I prefer the less irksome True or False to do error checking.
 Exceptions seem too heavyweight for simple problems.

Just write simple programs as if errors never happen; if an exception is
raised, the program prints a vaguely useful message and exits.

Besides, this complaint is incoherent.  One needs at least as much
structure to check an error code as to catch an exception.

 3. Philosophically I think exception handling is the wrong approach to 
 error management.

There are better ways to handle errors than Python's exception system.
Passing error codes around manually is most definitely not one of them.

(One of the main reasons I ditched Perl in favour of Python is the
former's insistence on returning error codes for I/O and system calls.)

-- [mdw]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Tim Harig
On 2010-12-02, Harishankar v.harishan...@gmail.com wrote:
 Actually, finer grained error handling commonly covers up bugs.  If you
 want to find bugs, you want to make the program prone to crashing if a
 bug is present.  It is all too easy to accidently mistake the return
 value of a function as error condition and handle it rather the letting
 the program crash.  By separating the results from the transmission of
 error conditions (in effect taking error conditions out of band) then
 you make it much harder to make such a mistake because you have to
 explicity indicate which error conditions your code is capable of
 generating.

 Doesn't the same finer grained exception mechanism make it prone to the 
 same problems? 

Exception handling is a move away from fine grained handling.  If in
IOError is raised by a parser, I don't need to know at exactly which
line the error occured.  All I need to know is that the file is somehow
unreadable; and that is why the parser failed.  Therefore, none of
the parser code should be handling IOError because it is being handled
higher up in the stack.  Since I expected that the parser might have
problemes reading files, for problems that have nothing to do with my
code, I explicity catch that error if it occurs.  I am not expecting an
IndexError from the parser and I don't bother to catch it.  If the parser
code does raise an IndexError, then my program crashes and I know that I
have a bug in the parsing code.  The call trace will tell me where that
error occurs.  I can watch that section of code in debugger to find out
exactly what went wrong.

 Actually return values of functions which I write myself can be as 
 specific and to the point. I could make it as fuzzy or as precise as I 
 like. This is no doubt, something that I could emulate with an exception 
 as well, but only make it slightly more complex with no obvious benefit.

You seem to be making it complex because you are still trying to be too
fine grained in handling each exception where it occurs as opposed to
handing where the logic makes sense that it should be handled and because
you are trying to code too defensively against your own code.  Exception
handling does require a different focus from handling errors from return
values alone.

 As I said before, the way exceptions are caught seem to me to be the most 
 confusing bit. Non-atomic operations always worry me. What if my function 
 which is wrapped inside a try block has two different statements that 
 raised the same exception but for different reasons? With error handling 
 I could probably handle it right below the statement which was called and 
 thus reduce the problem???

If you are having that issue, then you are likely placing the try blocks
at too low of a level in your code.  In general you will find that
most systems have a gateway function as an entry point to the system.
If there is not one already, then create such a function in you code.
The parse function in my code above would be an example of such a
gateway function.  Beneath that function, you don't need to know exactly
where the error occured, you just need to know the nature of the error and
have general error handling procedures for each kind of error that you
expect might occur.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Jean-Michel Pichavant

Harishankar wrote:
As I said before, the way exceptions are caught seem to me to be the most 
confusing bit. Non-atomic operations always worry me. What if my function 
which is wrapped inside a try block has two different statements that 
raised the same exception but for different reasons? With error handling 
I could probably handle it right below the statement which was called and 
thus reduce the problem???


  


Exception actually are the solution as you can give an unlimitted 
quantity of information:


def myfunction(self):
   error = myfuncException('a meaninful message')
   # error 1
   error.blame = whateverobjectresponsibleoftheerror
   # error 2
   error.blame = anotherobject_anothercause  
  
   raise error


try:
   myfunction()
except myfuncException, exception:
   cause = exception.blame
   # you can inspect the 'cause' for specific handling


In a more general and simple manner, you can tune the error feedback of 
exceptions by changing the message of the exception. Using different 
exception classes is also an obvious way to do it.


But my point was that you can  also set attributes to the exception 
you're raising with reference to almost anything at the time the 
exception occurs. And that is a very cool way to give precise feedback 
to exception handlers.
  
JM

--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread MRAB

On 02/12/2010 16:12, Tim Harig wrote:

On 2010-12-02, Harishankarv.harishan...@gmail.com  wrote:

I understand that the error vs exception debate is quite a big one in the
programming community as a whole and I don't consider myself very


Actually, I thought that debate was resolved years ago.  I cannot think of
a single recently developed programming language that does not provide
exception handling mechanisms because they have been proven more reliable.


Python. I do understand both sides of the issue. Exceptions seem to be
generally more reliable but I feel they add a lot of complexity
particular when a lot of code is placed in a try block.


Lines of code is one measure of complexity.  Each line of code has a small
chance of containing a bug.  The more lines of code that you have, then the
more likely that one of them contains a bug.  Exceptions, by placing error
handling code in fewer places, requires much fewer lines of code then
requiring error handling code after each call that might produce an error
condition.

The operations of propogating an error up to the higher level logic of
the program is another measure.  In languages without exception handling,
careful planning is needed to pass error conditions up through the call
stack until they reach a high enough level in the logic that decisions
can be made about how to handle them.  Even further planning must be
taken so that when the error condition reaches level where it needs to
be handled, that enough information about the error is present to know
exactly what went wrong so that it can figure out what to do about it.
This usually involves using globals like errorno to pass out of band
information about the error.  Sometimes you even need to know about how
the error affect intermediate levels, did the intermediate code attempt
to handle the condtion and fail?  The Openssl error handling system,
that creates an error logging chain is an example of just how complex
this can become.  You gain all of this functionality automatically
through exception mechanisms; without all of the complexity.


When writing the C code for the new regex module I thought that it
would've been easier if I could've used exceptions to propagate errors
and unwind the stack, instead of having to return an error code which
had to be checked by the caller, and then have the caller explicitly
return an error code to /its/ caller.

Automatic garbage collection would also have been nice.

You don't realise how nice it is to have such things until you have to
go without them.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Paul Rubin
MRAB pyt...@mrabarnett.plus.com writes:
 When writing the C code for the new regex module I thought that it
 would've been easier if I could've used exceptions to propagate errors
 and unwind the stack, instead of having to return an error code which
 had to be checked by the caller, and then have the caller explicitly
 return an error code to /its/ caller.

That's called longjmp.

 Automatic garbage collection would also have been nice.

alloca might help.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Terry Reedy
Aside from the other issues raised, I will just note that is more common 
to return None when there is no answer (for whatever reason) rather than 
False and explicitly compare 'is None' than 'is False'.


--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Tim Harig
On 2010-12-02, Paul Rubin no.em...@nospam.invalid wrote:
 MRAB pyt...@mrabarnett.plus.com writes:
 When writing the C code for the new regex module I thought that it
 would've been easier if I could've used exceptions to propagate errors
 and unwind the stack, instead of having to return an error code which
 had to be checked by the caller, and then have the caller explicitly
 return an error code to /its/ caller.

 That's called longjmp.

The problem is that you might have partially allocated data structures that
you need to free before you can go anywhere.  Jumping up several levels,
without letting the intermediate levels do their cleanup could easily lead
to a memory leak or worse.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Terry Reedy

On 12/2/2010 9:56 AM, Harishankar wrote:


There are some reasons why I hate exceptions but that is a different
topic. However, in short I can say that personally:

1. I hate try blocks which add complexity to the code when none is
needed. Try blocks make code much more unreadable in my view and I use it
only for the built-in exceptions when absolutely needed.

2. I prefer the less irksome True or False to do error checking.
Exceptions seem too heavyweight for simple problems.


It turns out that try block are computationally lighter weight (faster) 
for normal execution ;-)



3. Philosophically I think exception handling is the wrong approach to
error management. I have never grown up programming with exceptions in C
and I couldn't pick up the habit with python either. Did I mention that I
detest try blocks? try blocks seem ugly and destroy code clarity at least
in my view. And enclosing single statements under separate try blocks
seem to add a lot of clutter.


Having also come to Python directly from C, I can sympathize. It took me 
a while to adjust.


--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Paul Rubin
Tim Harig user...@ilthio.net writes:
 That's called longjmp.

 The problem is that you might have partially allocated data structures
 that you need to free before you can go anywhere.

Alloca can help with that since the stack stuff gets released by the
longjmp.  Alternatively you can have an auxiliary stack of cleanup
records that the longjmp handler walks through.  Of course if you do
that, you're halfway towards reinventing exceptions.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Grant Edwards
On 2010-12-02, Paul Rubin no.em...@nospam.invalid wrote:
 MRAB pyt...@mrabarnett.plus.com writes:
 When writing the C code for the new regex module I thought that it
 would've been easier if I could've used exceptions to propagate errors
 and unwind the stack, instead of having to return an error code which
 had to be checked by the caller, and then have the caller explicitly
 return an error code to /its/ caller.

 That's called longjmp.

In theory.

In practice, using longjump for that without blowing your foot off
isn't easy.

 Automatic garbage collection would also have been nice.

 alloca might help.

And that's almost as easy to screw up. :)

-- 
Grant Edwards   grant.b.edwardsYow! I want EARS!  I want
  at   two ROUND BLACK EARS
  gmail.comto make me feel warm
   'n secure!!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread MRAB

On 02/12/2010 18:09, Paul Rubin wrote:

MRABpyt...@mrabarnett.plus.com  writes:

When writing the C code for the new regex module I thought that it
would've been easier if I could've used exceptions to propagate errors
and unwind the stack, instead of having to return an error code which
had to be checked by the caller, and then have the caller explicitly
return an error code to /its/ caller.


That's called longjmp.


The problem with that is that the caller might have to do some tidying
up, such as deallocation.

Exceptions give the caller the chance of catching it (ideally in a
'finally' block), tidying up, and then propagating.


Automatic garbage collection would also have been nice.


alloca might help.


I didn't know about that.

It looks like that's allocated on the stack, and the allocation I'm
talking must be on the heap, so it's not suitable anyway.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Tim Harig
On 2010-12-02, Paul Rubin no.em...@nospam.invalid wrote:
 Tim Harig user...@ilthio.net writes:
 That's called longjmp.

 The problem is that you might have partially allocated data structures
 that you need to free before you can go anywhere.

 Alloca can help with that since the stack stuff gets released by the
 longjmp.  Alternatively you can have an auxiliary stack of cleanup

alloca() only helps if you actually *want* the data stored on the stack.
There are many reasons one might prefer or need that the data in the heap.

 longjmp.  Alternatively you can have an auxiliary stack of cleanup
 records that the longjmp handler walks through.  Of course if you do

Only if you already have pointers to *all* of the data structures at
the point where you put your setjmp().  This approach is error prone.

 records that the longjmp handler walks through.  Of course if you do
 that, you're halfway towards reinventing exceptions.

Exactly.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Paul Rubin
Tim Harig user...@ilthio.net writes:
 longjmp.  Alternatively you can have an auxiliary stack of cleanup
 records that the longjmp handler walks through.  Of course if you do

 Only if you already have pointers to *all* of the data structures at
 the point where you put your setjmp().

The setjmp point only has to know where the aux stack is and its depth
when the longjmp happens.  The cleanup records contain any necessary
pointers to data structures that need freeing.  That is basically how
try/finally would do it too.  This is pretty standard stuff.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Tim Harig
On 2010-12-02, Paul Rubin no.em...@nospam.invalid wrote:
 Tim Harig user...@ilthio.net writes:
 longjmp.  Alternatively you can have an auxiliary stack of cleanup
 records that the longjmp handler walks through.  Of course if you do

 Only if you already have pointers to *all* of the data structures at
 the point where you put your setjmp().

 The setjmp point only has to know where the aux stack is and its depth
 when the longjmp happens.  The cleanup records contain any necessary
 pointers to data structures that need freeing.  That is basically how
 try/finally would do it too.  This is pretty standard stuff.

I am not talking about what setjmp() has to do, I am talking about what
*you* have to do after setjmp() returns.  If you have allocated memory in
intermediate functions and you don't have a reference to them outside of
the functions that longjmp() bypasses from returning properly (and thus
either not clearning data structures or returning a reference to those data
structures as it normally would) then you have potential memory leaks,
dangling pointers, etc.

I am not saying that this cannot be done.  What I am saying is that it
is inherently error prone.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Steve Holden
On 12/2/2010 1:31 PM, Terry Reedy wrote:
 It turns out that try block are computationally lighter weight (faster)
 for normal execution ;-)

Though that alone would hardly be sufficient reason to use them.

regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
PyCon 2011 Atlanta March 9-17   http://us.pycon.org/
See Python Video!   http://python.mirocommunity.org/
Holden Web LLC http://www.holdenweb.com/

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread MRAB

On 02/12/2010 19:15, Tim Harig wrote:

On 2010-12-02, Paul Rubinno.em...@nospam.invalid  wrote:

Tim Hariguser...@ilthio.net  writes:

longjmp.  Alternatively you can have an auxiliary stack of cleanup
records that the longjmp handler walks through.  Of course if you do


Only if you already have pointers to *all* of the data structures at
the point where you put your setjmp().


The setjmp point only has to know where the aux stack is and its depth
when the longjmp happens.  The cleanup records contain any necessary
pointers to data structures that need freeing.  That is basically how
try/finally would do it too.  This is pretty standard stuff.


I am not talking about what setjmp() has to do, I am talking about what
*you* have to do after setjmp() returns.  If you have allocated memory in
intermediate functions and you don't have a reference to them outside of
the functions that longjmp() bypasses from returning properly (and thus
either not clearning data structures or returning a reference to those data
structures as it normally would) then you have potential memory leaks,
dangling pointers, etc.

I am not saying that this cannot be done.  What I am saying is that it
is inherently error prone.


Automatic garbage collection is nice to have when using exceptions
precisely because it's automatic, so unwinding the stack is much safer.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Paul Rubin
Tim Harig user...@ilthio.net writes:
 I am not talking about what setjmp() has to do, I am talking about what
 *you* have to do after setjmp() returns.  If you have allocated memory in
 intermediate functions and you don't have a reference to them outside of
 the functions that longjmp() bypasses from returning properly (and thus
 either not clearning data structures or returning a reference to those data
 structures as it normally would) then you have potential memory leaks,
 dangling pointers, etc.

Sure, that's what the aux stack is for--you put any such references into
it, for the setjmp handler to find later.  You do that BEFORE setjmp
returns, of course.

 I am not saying that this cannot be done.  What I am saying is that it
 is inherently error prone.

I suppose so, but so is everything else in C.  On the overall scale of
C-related hazards, this particular one isn't so bad if you code in a
consistent style and are disciplined about recording the cleanups.

You could also use something like an obstack, which is a stack allocated
on the heap, so it persists after the control stack returns, but you can
release the whole thing in one operation.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Tim Harig
On 2010-12-02, MRAB pyt...@mrabarnett.plus.com wrote:
 On 02/12/2010 19:15, Tim Harig wrote:
 On 2010-12-02, Paul Rubinno.em...@nospam.invalid  wrote:
 Tim Hariguser...@ilthio.net  writes:
 longjmp.  Alternatively you can have an auxiliary stack of cleanup
 records that the longjmp handler walks through.  Of course if you do

 Only if you already have pointers to *all* of the data structures at
 the point where you put your setjmp().

 The setjmp point only has to know where the aux stack is and its depth
 when the longjmp happens.  The cleanup records contain any necessary
 pointers to data structures that need freeing.  That is basically how
 try/finally would do it too.  This is pretty standard stuff.

 I am not talking about what setjmp() has to do, I am talking about what
 *you* have to do after setjmp() returns.  If you have allocated memory in
 intermediate functions and you don't have a reference to them outside of
 the functions that longjmp() bypasses from returning properly (and thus
 either not clearning data structures or returning a reference to those data
 structures as it normally would) then you have potential memory leaks,
 dangling pointers, etc.

 I am not saying that this cannot be done.  What I am saying is that it
 is inherently error prone.

 Automatic garbage collection is nice to have when using exceptions
 precisely because it's automatic, so unwinding the stack is much safer.

Indeed.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Tim Harig
On 2010-12-02, Paul Rubin no.em...@nospam.invalid wrote:
 Tim Harig user...@ilthio.net writes:
 I am not talking about what setjmp() has to do, I am talking about what
 *you* have to do after setjmp() returns.  If you have allocated memory in
 intermediate functions and you don't have a reference to them outside of
 the functions that longjmp() bypasses from returning properly (and thus
 either not clearning data structures or returning a reference to those data
 structures as it normally would) then you have potential memory leaks,
 dangling pointers, etc.

 Sure, that's what the aux stack is for--you put any such references into
 it, for the setjmp handler to find later.  You do that BEFORE setjmp
 returns, of course.

If you miss something, you are in trouble.

There is a concept of variable life that is measured by how many lines
separate the use of variable from its first use to its last.  By using
setjmp/longjmp, you effectively extend the life of these variables,
potentially through several files, to at least as long as the jump.  If
there are several function calls in depth, there may be quite a lot of
space that you have to check to make sure that you have not missed
anything.

 I am not saying that this cannot be done.  What I am saying is that it
 is inherently error prone.

 I suppose so, but so is everything else in C.  On the overall scale of
 C-related hazards, this particular one isn't so bad if you code in a
 consistent style and are disciplined about recording the cleanups.

 You could also use something like an obstack, which is a stack allocated
 on the heap, so it persists after the control stack returns, but you can
 release the whole thing in one operation.

By working the error back up through the call stack, you can keep track of
the variables and allocations in each function isolated to that function.
The smaller each function is, the easier and less error prone it will be
to theck it is to check.  That makes it much easier to make sure that
you have not missed anything.  Essentially, you can validate that each
function correctly handles is allocations rather then having to validate
the setjmp/longjmp structure as a whole.  To use Joe Armstrong's phrase,
it makes the impossible merely difficult.

Back to the topic, by using Python with its exceptions and garbage
collection, all of this is a moot point.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Ben Finney
Harishankar v.harishan...@gmail.com writes:

 On Thu, 02 Dec 2010 22:19:25 +1100, Ben Finney wrote:

  More details of the problem you're trying to solve would help with
  giving specific advice.

 I'm writing functions with multiple points of failure exits. I use
 return False as a way to flag the error condition rather than raising
 exceptions.

That's not much detail. Based only on that, I would say you should be
raising an exception at each “point of failure”, preferably of a type
defined for the purpose, instead of returning False.

 But under certain circumstances, the function can also return empty
 lists

The function returns boolean, list, and None types? That's very much a
case where the function is trying to do too many things with the return
value.

Raise exceptions for exceptional cases, and define the function
interface so that it's doing one clear job only. Often that involves
breaking a complicated function into several collaborating functions
with simpler interfaces.

-- 
 \“Pinky, are you pondering what I'm pondering?” “Umm, I think |
  `\   so, Brain, but three men in a tub? Ooh, that's unsanitary!” |
_o__)   —_Pinky and The Brain_ |
Ben Finney
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread John Nagle

On 12/2/2010 10:13 AM, Terry Reedy wrote:

Aside from the other issues raised, I will just note that is more common
to return None when there is no answer (for whatever reason) rather than
False and explicitly compare 'is None' than 'is False'.


   The basic problem is that the original design of Python lacked
a bool type.  Classic language design error.  It seems reasonable
to people not familiar with programming language history
to let True be equivalent to 1 and False be equivalent to 0, but
it doesn't work out well.

   Retrofitting a bool type never quite works right.  C/C++ went
through this decades ago.  The semantics of integers
are clear, and the semantics of booleans are clear, but the semantics
of mixed booleans and integers are not.  You get questions like the
one in this thread.

   Related questions include the semantics of

x = True + True

What's the value of x?  True?  2?  Is + between
two Bool items addition, logical OR, or an error?
The same problem applies to *.

   The arguments on either side can be seen in PEP 285, but
they gloss over the fact that the original design was botched.

   Similar design errors show up in other places in Python.
Using + for concatenation seemed reasonable, but didn't scale
out well, especially after NumPy's array type was introduced.

   [1,2,3] + [4,5,6]

and

   array([1,2,3]) + array([4,5,6])

produce quite different results.  Worse, what should

   array([1,2,3]) + [4,5,6]

do? It doesn't raise an exception.

I went to a talk by Alexander Stepanov at Stanford recently, where he
talked about problems in the fundamentals of programming.  This is
one of the issues that came up.  Defining addition in a way that
is not associative and commutative leads to problems, and breaks
generic algorithms.  If the basic operators follow the expected rules, 
generic algorithms will work on them.  That was botched in Python.


John Nagle
--
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Aahz
In article mailman.143.1291301807.2649.python-l...@python.org,
Harishankar  v.harishan...@gmail.com wrote:

There are some reasons why I hate exceptions but that is a different 
topic. However, in short I can say that personally:

1. I hate try blocks which add complexity to the code when none is 
needed. Try blocks make code much more unreadable in my view and I use it 
only for the built-in exceptions when absolutely needed.

2. I prefer the less irksome True or False to do error checking. 
Exceptions seem too heavyweight for simple problems.

Please demonstrate that using ``if`` blocks for True/False is impler and
cleaner than using ``try`` blocks to handle exceptions.
-- 
Aahz (a...@pythoncraft.com)   * http://www.pythoncraft.com/

Think of it as evolution in action.  --Tony Rand
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Harishankar
On Fri, 03 Dec 2010 08:06:35 +1100, Ben Finney wrote:

 Raise exceptions for exceptional cases, and define the function
 interface so that it's doing one clear job only. Often that involves
 breaking a complicated function into several collaborating functions
 with simpler interfaces.

This is probably what I should try to do. Of course my function returns 
only a list in most circumstances. Only in error does it return False. I 
mis-represented the None type for the empty list in my previous post, my 
apologies.

-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Harishankar
On Thu, 02 Dec 2010 16:52:57 +, Tim Harig wrote:

 If you are having that issue, then you are likely placing the try blocks
 at too low of a level in your code.  In general you will find that most
 systems have a gateway function as an entry point to the system. If
 there is not one already, then create such a function in you code. The
 parse function in my code above would be an example of such a gateway
 function.  Beneath that function, you don't need to know exactly where
 the error occured, you just need to know the nature of the error and
 have general error handling procedures for each kind of error that you
 expect might occur.

I think I might very well by using try blocks rather defensively rather 
than letting the code reach its logical conclusion in normal 
circumstances. This is why I think I find it a bit clunky. 

I think I understand the general trend of what you're saying. It 
definitely requires a mindset change. I still feel that user-defined 
exception classes might not be the way, but maybe I should allow the 
built-in exceptions which are thrown by library functions to follow its 
natural path upwards till it reaches the top level where it could be 
handled. 

Maybe I should handle the error only at the highest level (UI level) 
rather than returning False to flag errors. 

One of the reasons why I feared to do this is because I need to know each 
and every exception that might be thrown by the function and litter my 
top-level code with too many exception handlers.

-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Tim Harig
On 2010-12-03, Harishankar v.harishan...@gmail.com wrote:
 On Thu, 02 Dec 2010 16:52:57 +, Tim Harig wrote:

 If you are having that issue, then you are likely placing the try blocks
 at too low of a level in your code.  In general you will find that most
 systems have a gateway function as an entry point to the system. If
 there is not one already, then create such a function in you code. The
 parse function in my code above would be an example of such a gateway
 function.  Beneath that function, you don't need to know exactly where
 the error occured, you just need to know the nature of the error and
 have general error handling procedures for each kind of error that you
 expect might occur.

 I think I might very well by using try blocks rather defensively rather 
 than letting the code reach its logical conclusion in normal 
 circumstances. This is why I think I find it a bit clunky. 

That was the conclusion I was coming to.

 I think I understand the general trend of what you're saying. It 
 definitely requires a mindset change. I still feel that user-defined 
 exception classes might not be the way, but maybe I should allow the 
 built-in exceptions which are thrown by library functions to follow its 
 natural path upwards till it reaches the top level where it could be 
 handled. 

Look at it this way, in C you were constrained to place your error
handling code around ever function that might fail.  Now you are free
to place the error handling code wherever it makes sense to do so.
As a general rule, if, in C, your function would handle the error by
passing an error return value to the calling function, then the error
handling code should be higher up.

 Maybe I should handle the error only at the highest level (UI level) 
 rather than returning False to flag errors. 

I don't write many UIs; but, I normally consider the UI code to be yet
another subsystem.  In general, I find the best place to place error
handling code in the high level business logic of your application (which
might be what you actually meant by UI, to me the UI code is the code that
actually draws the interface), in the high level logic of the systems,
and in the bounderies between subsystems.  The exceptions caught at each
level depend on where the logic to handle the error is best applied.

 One of the reasons why I feared to do this is because I need to know each 
 and every exception that might be thrown by the function and litter my 
 top-level code with too many exception handlers.

Each exception has a place where it is better handled.  Wherever you
find boundaries between subsystems, think about what error conditions
that subsystem might encounter.  Subsystems dealing with are likely
to encounter io related errors, network subsystems network errors,
parsers validation errors etc.  Logic exceptions that indicate errors
in your code should be left alone entirely so that they may be easily
found. Look at the exceptions pertaining to these subsystems.

For each error reaching the boundery, think about whether you have enough
information within the module to handle the error in a constructive
manner or whether the error handling would benefit from information
further up in the program.  If you have all of the information that you
need then handle it in the main logic of that subsystem.  If not, pass
it up to the error handlers on top of the boundry.  When you get there,
make the same decision.

In general you only need to catch a handful of exceptions at each level.
The easy excpetions will be handled at lower levels.  The most difficult
exceptions will rise towards the top of the program until only the terminal
exceptions, that cannot be resolved are left with the inevitable result that
you should notify the user and exit, will remain.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Steven D'Aprano
On Thu, 02 Dec 2010 16:35:08 +, Mark Wooding wrote:

 3. Philosophically I think exception handling is the wrong approach to
 error management.
 
 There are better ways to handle errors than Python's exception system.

I'm curious -- what ways would they be?

I'm aware of three general exception handling techniques:

1. return a sentinel value or error code to indicate an exceptional case 
(e.g. str.find returns -1);

2. raise an exception (e.g. nearly everything else in Python);

3. set an error code somewhere (often a global variable) and hope the 
caller remembers to check it;

plus some de facto techniques sadly in common use:

4. dump core;

5. do nothing and produce garbage output.


What else is there?


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison with False - something I don't understand

2010-12-02 Thread Paul Rubin
Steven D'Aprano steve+comp.lang.pyt...@pearwood.info writes:
 There are better ways to handle errors than Python's exception system.
 I'm curious -- what ways would they be?
 I'm aware of three general exception handling techniques: ...
 What else is there?

The Erlang approach is to chop the application into a lot of very
lightweight processes, and let any process that encounters an error
simply crash.  A monitoring process notices the crashed process and
restarts it.  There is a supervision tree of uber-monitor processes
that restart crashed monitor proceses.  I haven't programmed in that
style myself and I'm not persuaded that it's better than what Python
does, but I think it's different from the stuff on your list, which is
an answer to your what else is there.  I do know that they write some
complex, very high reliability systems (phone switches) in Erlang.
-- 
http://mail.python.org/mailman/listinfo/python-list


Comparison with False - something I don't understand

2010-12-01 Thread Harishankar
When I run pychecker through my modules I get the message that 
comparisons with False is not necessary and that it might yield 
unexpected results.

Yet in some situations I need to specifically check whether False was 
returned or None was returned. Why is comparison with False so bad?

# example code which matches both False and None
if not var:
# do something

# specifically check if False is returned 
# I don't want None
if var == False:
   # do something

So how do you get around this? My functions return False and None under 
different circumstances. Should I raise exceptions instead? I feel it's 
unnecessary clutter to use exceptions unless absolutely no other solution 
is available and yet I have doubts about the False value.

-- 
Harishankar (http://harishankar.org http://lawstudentscommunity.com)

-- 
http://mail.python.org/mailman/listinfo/python-list