Re: Comparison

2014-09-23 Thread Steven D'Aprano
LJ wrote:

 I have a network in which the nodes are defined as dictionaries using the
 NetworkX package. Inside each node (each dictionary) I defined a
 dictionary of dictionaries holding attributes corresponding to different
 ways in which the node can be reached (this dictionaries I refer to as
 labels). At some point in my algorithm I am looping through some subset of
 nodes and through the labels in each node and I perform some joining
 checks with the labels of each node in another subset of nodes. To clarify
 I check for a feasibility condition in a pairwise manner for every label
 in one node and every label of another. This nested loop is taking time. I
 wonder if the fact of defining the labels using numpy instead of
 dictionaries could imply a faster way to perform this loop.

I doubt it very much. Python dicts are extremely fast, and it doesn't sound
like your problem is that each dict lookup is slow. It sounds like your
problem is that you are doing a lot of them.

If you have 100 labels in one node, and 100 labels in the other, and you are
doing:

for label_a in A:
for label_b in B:
is_feasible(label_a, label_b)

the total number of feasibility checks is 100*100 = 1, not the 200 that
you may be expecting. The bottleneck here is probably your is_feasible
check, called many times, not the dict look-ups.

But of course we cannot be sure without seeing your code, and we can't be
certain without running the profiler and seeing exactly where your
bottlenecks are.


-- 
Steven

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


Re: Comparison

2014-09-22 Thread Chris Angelico
On Tue, Sep 23, 2014 at 2:57 AM, LJ luisjoseno...@gmail.com wrote:
 Quick question here. In the code I am working on I am apparently doing a lot 
 of dictionary lookups and those are taking a lot of time.
 I looked at the possibility of changing the structure and I found about the 
 numpy structured arrays.
 The concrete question is: what would be the difference between using one or 
 the other in terms of performance? meaning looping and performing checks an 
 operations on them?

The lookups themselves almost certainly aren't actually taking the
time, unless you have some kind of crazy hash collision happening,
which is so statistically unlikely that it would have to have come
from malice. What's the code doing? What are you trying to accomplish?
It's much more likely that you have an algorithmic flaw than a data
type inefficiency.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Comparison

2014-09-22 Thread LJ
On Monday, September 22, 2014 1:12:23 PM UTC-4, Chris Angelico wrote:
 On Tue, Sep 23, 2014 at 2:57 AM, LJ luisjoseno...@gmail.com wrote:
 
  Quick question here. In the code I am working on I am apparently doing a 
  lot of dictionary lookups and those are taking a lot of time.
 
  I looked at the possibility of changing the structure and I found about the 
  numpy structured arrays.
 
  The concrete question is: what would be the difference between using one or 
  the other in terms of performance? meaning looping and performing checks an 
  operations on them?
 
 
 
 The lookups themselves almost certainly aren't actually taking the
 
 time, unless you have some kind of crazy hash collision happening,
 
 which is so statistically unlikely that it would have to have come
 
 from malice. What's the code doing? What are you trying to accomplish?
 
 It's much more likely that you have an algorithmic flaw than a data
 
 type inefficiency.
 
 
 
 ChrisA



Thank you for your reply.

Basically what is happening is the following:

I have a network in which the nodes are defined as dictionaries using the 
NetworkX package. Inside each node (each dictionary) I defined a dictionary of 
dictionaries holding attributes corresponding to different ways in which the 
node can be reached (this dictionaries I refer to as labels). 
At some point in my algorithm I am looping through some subset of nodes and 
through the labels in each node and I perform some joining checks with the 
labels of each node in another subset of nodes. To clarify I check for a 
feasibility condition in a pairwise manner for every label in one node and 
every label of another. This nested loop is taking time.
I wonder if the fact of defining the labels using numpy instead of dictionaries 
could imply a faster way to perform this loop.

I hope I was clear.

Thanks.

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


Re: Comparison

2014-09-22 Thread Chris Angelico
On Tue, Sep 23, 2014 at 3:38 AM, LJ luisjoseno...@gmail.com wrote:
 At some point in my algorithm I am looping through some subset of nodes and 
 through the labels in each node and I perform some joining checks with the 
 labels of each node in another subset of nodes. To clarify I check for a 
 feasibility condition in a pairwise manner for every label in one node and 
 every label of another. This nested loop is taking time.


Okay, that's where the issue is - you're doing a cross-match, that's
going to be comparing every label against every other.

You might be able to cache some references to part-way into the tree,
depending on how your code is written, but ultimately, you still need
to do all of those checks.

What's the definition of feasibility? Can you optimize that? Maybe
there's a way to do a rough check that cuts down the number you have
to do the exact check on.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Comparison Style

2013-04-27 Thread Roy Smith
In article mailman.1077.1366944517.3114.python-l...@python.org,
 Chris Angelico ros...@gmail.com wrote:

 If you switch the order of operands in that, the compiler won't help
 you. Plus it reads wrong. So the convention is still
 variable==constant.

I just found a nice example of putting the constant first.  I've just 
done a whole bunch of ugly math to find some slice limits.  To make sure 
they're sane, I'm writing:

assert 5 = i  j  original_song_count

I can't think of any way to write that which would be as clean and easy 
to read.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison Style

2013-04-27 Thread Terry Jan Reedy

On 4/27/2013 5:03 PM, Roy Smith wrote:

In article mailman.1077.1366944517.3114.python-l...@python.org,
  Chris Angelico ros...@gmail.com wrote:


If you switch the order of operands in that, the compiler won't help
you. Plus it reads wrong. So the convention is still
variable==constant.


I just found a nice example of putting the constant first.  I've just
done a whole bunch of ugly math to find some slice limits.  To make sure
they're sane, I'm writing:

 assert 5 = i  j  original_song_count

I can't think of any way to write that which would be as clean and easy
to read.


Chained comparisons like this are standard math notation, which is why 
Python 'does the right thing' with them.




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


Re: Comparison Style

2013-04-26 Thread Mark Lawrence

On 25/04/2013 21:35, Steve Simmons wrote:



The Ying Tong song - a classic of its time. But eminently suited to the
chorally challenged.



Released on a classic EP with Major Dennis Bloodnok's Rock and Roll Call 
Rumba, I'm walking Backwards for Christmas and Bluebottle Blues.


Bravado, bravado. What a voice! (What a bank balance!)

--
If you're using GoogleCrap™ please read this 
http://wiki.python.org/moin/GoogleGroupsPython.


Mark Lawrence

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


Re: Comparison Style

2013-04-25 Thread Chris Angelico
On Thu, Apr 25, 2013 at 3:49 PM, llanitedave llanited...@veawb.coop wrote:
 Given that

 s = some static value
 i = a value incremented during a loop

 I'm used to comparing them as

 if i == s:
 # some code

 But for some unknown reason I did a switch

 if s == i:
 # same code

 It didn't seem to make any difference at first glance, so I just got to 
 wondering --

It won't make any difference in any sort of sane code. If there's any
situation in which == is not reflexive, something seriously nasty is
going on.

 Is there a standard for comparison order?  Is there any kind of performance 
 difference?  Is there even a tradition for one or the other?  Are there any 
 gotchas?

It's conventional to compare variables to constants, not constants to
variables (even in C where there's the possibility of mucking up the
operator, most people still compare variables to constants). I'd
normally use i == s there, treating s as a constant for the purpose
of the loop. Unless you're deliberately being poetical, language such
as Three is the number thou shalt count is distinctly abnormal, so
saying if (5 == i) is equally awkward. It's nothing major; mostly
it's like the algebraic convention of putting the more-known elements
earlier in a term (eg 2πix - 2 is known, 3.14159 is mostly known,
i is imaginary but at least it's constant, and x is unknown).

 Do I need to get a hobby?

I thought programming WAS a hobby?

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


Re: Comparison Style

2013-04-25 Thread llanitedave
On Wednesday, April 24, 2013 10:57:49 PM UTC-7, Chris Angelico wrote:
 On Thu, Apr 25, 2013 at 3:49 PM, llanitedave llanited...@veawb.coop wrote:
 
  Given that
 
 
 
  s = some static value
 
  i = a value incremented during a loop
 
 
 
  I'm used to comparing them as
 
 
 
  if i == s:
 
  # some code
 
 
 
  But for some unknown reason I did a switch
 
 
 
  if s == i:
 
  # same code
 
 
 
  It didn't seem to make any difference at first glance, so I just got to 
  wondering --
 
 
 
 It won't make any difference in any sort of sane code. If there's any
 
 situation in which == is not reflexive, something seriously nasty is
 
 going on.
 
 
 
  Is there a standard for comparison order?  Is there any kind of performance 
  difference?  Is there even a tradition for one or the other?  Are there any 
  gotchas?
 
 
 
 It's conventional to compare variables to constants, not constants to
 
 variables (even in C where there's the possibility of mucking up the
 
 operator, most people still compare variables to constants). I'd
 
 normally use i == s there, treating s as a constant for the purpose
 
 of the loop. Unless you're deliberately being poetical, language such
 
 as Three is the number thou shalt count is distinctly abnormal, so
 
 saying if (5 == i) is equally awkward. It's nothing major; mostly
 
 it's like the algebraic convention of putting the more-known elements
 
 earlier in a term (eg 2πix - 2 is known, 3.14159 is mostly known,
 
 i is imaginary but at least it's constant, and x is unknown).
 
 



Thanks, Chris.  That's kind of along the lines of what I was thinking.  
Visually, the code just looked wrong, and I figure if for no other reasons than 
readability it's preferable in the traditional way.

It's nice to know, though, that the next time dyslexia strikes it's not 
necessarily a horrible thing.

 
  Do I need to get a hobby?
 
 
 
 I thought programming WAS a hobby?
 

I meant a safer, easier, and more mainstream hobby, like base jumping or 
motorcycle aerobatics or something.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison Style

2013-04-25 Thread Chris Angelico
On Fri, Apr 26, 2013 at 12:19 AM, llanitedave llanited...@veawb.coop wrote:
 On Wednesday, April 24, 2013 10:57:49 PM UTC-7, Chris Angelico wrote:
 I thought programming WAS a hobby?


 I meant a safer, easier, and more mainstream hobby, like base jumping or 
 motorcycle aerobatics or something.

Good point. With the sort of thinking you're demonstrating here, you
should consider a job working with Spike Milligna (the well-known
typing error). I believe there ought to be an office cubicle available
for you in one of the excellent organizations devoted to Milliganesque
thinkers and computer programmers - the walls are nicely padded...

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


Re: Comparison Style

2013-04-25 Thread Steve Simmons
Chris Angelico ros...@gmail.com wrote:

With the sort of thinking you're demonstrating here, you
should consider a job working with Spike Milligna (the well known typing error).

Errr ,  I think you'll find that he's joined the choir invisibule. Mind you,  
he did say he was ill! 

Sent from a Galaxy far far away
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison Style

2013-04-25 Thread llanitedave
On Thursday, April 25, 2013 11:31:04 AM UTC-7, Steve Simmons wrote:
 Chris Angelico ros...@gmail.com wrote:
 
 
 
 With the sort of thinking you're demonstrating here, you
 
 should consider a job working with Spike Milligna (the well known typing 
 error).
 
 
 
 Errr ,  I think you'll find that he's joined the choir invisibule. Mind you,  
 he did say he was ill! 
 
 
 
 Sent from a Galaxy far far away


Did you ever hear him sing?  He's better off in the choir inaudible.

As am I...
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison Style

2013-04-25 Thread Neil Cerutti
On 2013-04-25, llanitedave llanited...@veawb.coop wrote:
 Errr ,  I think you'll find that he's joined the choir
 invisibule. Mind you,  he did say he was ill! 
 
 Sent from a Galaxy far far away

 Did you ever hear him sing?  He's better off in the choir
 inaudible.

Well I've never heard either one.

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


Re: Comparison Style

2013-04-25 Thread Steve Simmons
llanitedave llanited...@veawb.coop wrote:

On Thursday, April 25, 2013 11:31:04 AM UTC-7, Steve Simmons wrote:
 Chris Angelico ros...@gmail.com wrote:
 
 
 
 With the sort of thinking you're demonstrating here, you
 
 should consider a job working with Spike Milligna (the well known
typing error).
 
 
 
 Errr ,  I think you'll find that he's joined the choir invisibule.
Mind you,  he did say he was ill! 
 
 
 
 Sent from a Galaxy far far away


Did you ever hear him sing?  He's better off in the choir inaudible.

As am I...
-- 
http://mail.python.org/mailman/listinfo/python-list

The Ying Tong song -  a classic of its time. But eminently suited to the 
chorally challenged. 

Sent from a Galaxy far far away-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison Style

2013-04-25 Thread Chris Angelico
On Fri, Apr 26, 2013 at 12:37 PM, Dennis Lee Bieber
wlfr...@ix.netcom.com wrote:
 On Thu, 25 Apr 2013 15:57:49 +1000, Chris Angelico ros...@gmail.com
 declaimed the following in gmane.comp.python.general:
 It's conventional to compare variables to constants, not constants to
 variables (even in C where there's the possibility of mucking up the
 operator, most people still compare variables to constants).

 The main reason for /literal/ first is to trap C/C++ assignment as
 expression.

 if (x = 5)

 ends up assigning x the value 5 and THEN, since 5 is true executing
 the then part.

 if (5 = x)

 OTOH is a compiler error.


Aware of this. My point is that, even though there's a good reason for
putting the constant first, it's still FAR more common to put the
variable first. Also, this protection helps only when the constant
is actually something the compiler knows is a constant - it doesn't
work in a search function, for instance:

char *strchr(char *string, char findme) {
while (*string) {
if (*string==findme) return string;
++string;
}
return 0;
}

If you switch the order of operands in that, the compiler won't help
you. Plus it reads wrong. So the convention is still
variable==constant.

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


Re: Comparison Style

2013-04-25 Thread Dave Angel

On 04/25/2013 10:48 PM, Chris Angelico wrote:

SNIP


Also, this protection helps only when the constant
is actually something the compiler knows is a constant - it doesn't
work in a search function, for instance:

char *strchr(char *string, char findme) {
 while (*string) {
 if (*string==findme) return string;
 ++string;
 }
 return 0;
}


Sure, but if I were coding in C again, I'd have made that function signature

char *strchr(char *string, const char findme) {
   or maybe
char *strchr(const char *string, const char findme) {



If you switch the order of operands in that, the compiler won't help
you.


Yes, it would.


Plus it reads wrong. So the convention is still
variable==constant.


In my case, after having it drilled in that you're supposed to put the 
constant first, I realized that I never had any problem with using =, 
because as soon as I questioned the order, I just double-checked that I 
was using ==.  At that point, there was no longer any benefit to making 
the order backwards.



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


Re: comparison between non-comparable objects

2013-01-07 Thread Dave Angel
On 01/08/2013 12:28 AM, Kelvin Li wrote:
 The language reference says:

 ...the choice whether one object [of built-in type] is considered
 smaller or larger than another one is made arbitrarily...

When quoting some online source, please give a reference link. It took
me a while to find the following page with your quote in it:


http://docs.python.org/3.3/reference/expressions.html
http://docs.python.org/3.3/reference/expressions.htm
   in section 6.9  Comparisons

 but that seems to be Python 2 behavior; Python 3 apparently raises a
 TypeError. Does the documentation need updating?


That sentence is correct in context.  The bullet items there are labeled
Comparison of objects of the same type...  And the particular bullet
also qualifies the type of the two objects being compared:Most
other objects of built-in types...



Earlier in the same section, it considers the case of comparing objects
of DIFFERENT type.

 while the , , = and = operators raise a TypeError
http://docs.python.org/3.3/library/exceptions.html#TypeError when
comparing objects of different types that do not implement these
operators for the given pair of types


-- 

DaveA

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


Re: comparison between non-comparable objects

2013-01-07 Thread Kelvin Li
 When quoting some online source, please give a reference link. It took
 me a while to find the following page with your quote in it:
 
 
 http://docs.python.org/3.3/reference/expressions.html
 http://docs.python.org/3.3/reference/expressions.htm
in section 6.9  Comparisons

Sorry about that. Thanks for finding the link.

  but that seems to be Python 2 behavior; Python 3 apparently raises a
  TypeError. Does the documentation need updating?
 
 
 That sentence is correct in context.  The bullet items there are labeled
 Comparison of objects of the same type...  And the particular bullet
 also qualifies the type of the two objects being compared:Most
 other objects of built-in types...

Got it, I was confusing built-in types with built-in functions--I
incorrectly thought object(), for example, returned an object of a
built-in type, and was behaving differently in Python 2 and 3:

object()  object()

Thanks,
Kelvin

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


Re: Comparison operators in Python

2011-06-02 Thread Terry Reedy

On 6/1/2011 8:44 PM, harrismh777 wrote:

Ian Kelly wrote:


 ?? wrote

integer. However comparison between a string and an integer seems to
be permitted. Is there any rationale behind this ?



It allows things like sorting of heterogeneous lists. It's generally
viewed as a wart, though, and it was fixed in Python 3:


This was a Python 1.0 idea that Guido decided was more bug-inducing than 
useful.



Just another example (excluding print 1/2 and unicode) where 3.x seems
to be completely compatible with 2.x/ (tongue-in-cheek)


Arbitrary comparisons were broken and effectively deprecated about a 
decade ago with the introduction of the complex type. Just another 
example where 3.x completes a process of change started years before.


--
Terry Jan Reedy

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


Re: Comparison operators in Python

2011-06-02 Thread Michael Sparks
On Jun 2, 1:44 am, harrismh777 harrismh...@charter.net wrote:
..
     Just another example (excluding  print  1/2  and  unicode) where 3.x
 seems to be completely compatible with 2.x/   (tongue-in-cheek)

One of the key purposes of the 3.x line of code is to get rid of warts
in the language. As a result, if someone is relying on warts, then
their code will break when changing from 2.x to 3.x.

IMO, this is actually a good thing since it encourages the reduction
in warty code. (People who want to use 2.x and 3.x can either use 2to3
and maintain 2to3-able code or write code that works in both 2.x and
3.x - which is eminently doable)

 (do Brits say tongue-in-cheek?)

Yes.


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


Re: Comparison operators in Python

2011-06-01 Thread Jussi Piitulainen
Anirudh Sivaraman writes:

 I am a relative new comer to Python. I see that typing is strongly
 enforced in the sense you can't concatenate or add a string and an
 integer. However comparison between a string and an integer seems to
 be permitted. Is there any rationale behind this ?

In Python 3 it is an error.

Python 3.1.1 (r311:74480, Feb  8 2010, 14:06:51) 
[GCC 4.4.3] on linux2
Type help, copyright, credits or license for more information.
 3  'kolme'
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: unorderable types: int()  str()
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison operators in Python

2011-06-01 Thread Ian Kelly
On Wed, Jun 1, 2011 at 12:50 PM, Anirudh Sivaraman sk.anir...@gmail.com wrote:
 Hi

 I am a relative new comer to Python. I see that typing is strongly
 enforced in the sense you can't concatenate or add a string and an
 integer. However comparison between a string and an integer seems to
 be permitted. Is there any rationale behind this ?

It allows things like sorting of heterogeneous lists.  It's generally
viewed as a wart, though, and it was fixed in Python 3:

Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit
(Intel)] on win32
Type help, copyright, credits or license for more information.
 'x'  5
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: unorderable types: str()  int()

Cheers,
Ian
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Comparison operators in Python

2011-06-01 Thread harrismh777

Ian Kelly wrote:

integer. However comparison between a string and an integer seems to
  be permitted. Is there any rationale behind this ?

It allows things like sorting of heterogeneous lists.  It's generally
viewed as a wart, though, and it was fixed in Python 3:



   Just another example (excluding  print  1/2  and  unicode) where 3.x 
seems to be completely compatible with 2.x/   (tongue-in-cheek)



(do Brits say tongue-in-cheek?)


:)


   ... just saying.
--
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


  1   2   3   >