Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-04 Thread Erik Max Francis

Antoon Pardon wrote:


Maybe I'm going to be pedantic here, but I fear that your code won't
work with matrices. The problem is that multiplication is not
commutative with matrices. This means that matrices have two divisions a right
and a left division. A far as I know the / operator usaly implements
the left division while solving is done by using a right division.

So your code will probably fail when applied to matrices.


You're right in your general point, but usually division between 
matrices isn't defined at all because of this ambiguity.  However the 
general point can still exist between `solveLeft` and `solveRight` 
functions which do something along the lines of a*b**-1 and a**-1*b.  A 
single `solve`, of course, would choose one of these, and syntactically 
it might be quite reasonable to define matrix division that does one of 
these and have a single `solve` function that accomplishes it.


Therefore, the general point about polymorphism still stands.

--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  It is human nature to think wisely and act foolishly.
   -- Anatole France
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-04 Thread Antoon Pardon
On 2008-08-01, Terry Reedy [EMAIL PROTECTED] wrote:
 Nevertheless, I think this is probably the best example of the
 enhanced polymorphism of if x yet.  I'm kind of surprised no one
 came up with it.)

 I think of Python code as 'generic' rather than 'polymorphic'.  I am not 
 sure if that is a real difference or not, since I am a bit fuzzy on the 
 meaning of 'polymorphic' in this context.

 The generality of 'if x:' depends on the context.  If x is defined as a 
 number by doc or previous code (or possibly even by subsequent code), 
 then 'if x:' is equivalent to 'if x != 0:'.  At this point, it is a 
 stylistic argument which to use.

 But here is an example where 'if x:' is more generic.

 def solve(a,b):
 'a and b such that b/a exists'
 if a:
return a/b
 else:
raise ValueError('a not invertible, cannot solve'

 Now suppose we have a matrix class (2x2 for simplicity and realism).
 Its __bool__ (3.0) method implements 'is non-singular'.  As written 
 above, solve(mat,vec) works (with compatible mat and vec sizes), but it 
 would not with 'if a != 0:'.

 Of course, the issue goes away by not looking before the leap:

 def solve(a,b):
  return a/b
  # let callers deal with exceptions
 or
  try:
 return a/b
  except...
# raise customized error

Maybe I'm going to be pedantic here, but I fear that your code won't
work with matrices. The problem is that multiplication is not
commutative with matrices. This means that matrices have two divisions a right
and a left division. A far as I know the / operator usaly implements
the left division while solving is done by using a right division.

So your code will probably fail when applied to matrices.

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-04 Thread Terry Reedy



Erik Max Francis wrote:

Antoon Pardon wrote:

[responding to me]

Maybe I'm going to be pedantic here, but I fear that your code won't
work with matrices. The problem is that multiplication is not
commutative with matrices. This means that matrices have two divisions 
a right

and a left division. A far as I know the / operator usaly implements
the left division while solving is done by using a right division.

So your code will probably fail when applied to matrices.


Your remarks are correct as far as they go, but..

You're right in your general point, but usually division between 
matrices isn't defined at all because of this ambiguity.  However the 
general point can still exist between `solveLeft` and `solveRight` 
functions which do something along the lines of a*b**-1 and a**-1*b.  A 
single `solve`, of course, would choose one of these, and syntactically 
it might be quite reasonable to define matrix division that does one of 
these and have a single `solve` function that accomplishes it.


Therefore, the general point about polymorphism still stands.


as Eric suggests, I was assuming that details would be defined to make 
my example work.  The context was the challenge to find an example 
where, for instance, 'if x:' would work but something more specific like 
'if x != 0:' would not.  My abstract answer was number-like class with 
division that is not valid for the class's null object.  The concrete 
answer was an incomplete instantiation of that for matrices.  Given the 
critique, polynomial division might be a better example since polynomial 
multiplication is commutative while  both ()(if allowed) and (0,) as 
polyomials might well be defined as != to numeric 0.  I suspect there 
are other algebra classes that work for this or other examples, but it 
has been a loong time since I took abstract algebra.


Actually I sort of worked too hard ;-).
The decimal module breaks the transitivity of equality!

 import decimal as d
 z=d.Decimal('0.0')
 z==0
True
 z==0.0
False
 0==0.0
True

So if someone wrote 'if x == 0.0:' instead of 'if not x:' (perhaps to 
raise an exception with explanation for unusable input), the former 
would not work.


tjr

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-01 Thread Antoon Pardon
On 2008-08-01, Carl Banks [EMAIL PROTECTED] wrote:
 On Jul 31, 1:27 pm, Chris Mellon [EMAIL PROTECTED] wrote:
 I'm really not sure where you're going with this or what you're trying
 to prove. if x is a duck-type test for a boolean value. Obviously if
 you know the type and want a more *specific* test, then you can use an
 explicit one. Any time you don't know or don't care about a more
 specific type than something which probably is boolean true, or any
 time where you know the boolean semantics of the type and want to drop
 some typing, you can use if x. The more specific test is what you'd
 use if you want more specific results. What's complicated about this
 idea?

 Many people trumpet that if x makes your code more polymorphic
 whenever this comes up--in fact you just repeated the claim--without
 ever considering how rarely this more extensive polymorphism comes up
 in practice.   I was calling them out to say prove to me that it
 actually happens.

 I believe it's very rare not to know enough about the expected type
 that explicit tests won't work.  We've uncovered a few examples of it
 in this thread, but IMO we haven't uncovered any sort of broad, wide-
 ranging use cases.

I was reading this thread and was wondering about the following problem.

I have a loop that continuously calculates something. I also have a
producer that may produce extra input that can influence the
calculations. The producer can also indicate the loop should finish.

So the result of produce can be three things:

  1) A not empty sequence; indicating available input.

  2) An empty sequence; indicating no input available now.

  3) None; indicating the end of the calculations.


So the loop essentially looks like this:

while 1:
  extra = produce()
  if extra is None:
break
  for el in extra:
adjust_with(el)
  calculate()


I now have the following question for people who argue that if x
is more polymorphic. I could subclass list, so that instances
of this new sequence would always behave as true, even if they are
empty.  I could then rewrite my loop as follows:

while 1:
  extra = produce()
  if not extra:
break
  for el in extra:
adjust_with(el)
  calculate()

Is this second loop now more polymorphic as the first?

Personnaly I would argue that the first loop with the more specific
test is more polymorphic in this case, as it works with the standard
sequence semantics of python; so the first loop will work with
produce, producing any kind of sequence while the second loop
will only work with produce producing a specific kind of sequence.

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-01 Thread Erik Max Francis

Antoon Pardon wrote:


I now have the following question for people who argue that if x
is more polymorphic. I could subclass list, so that instances
of this new sequence would always behave as true, even if they are
empty.  I could then rewrite my loop as follows:

while 1:
  extra = produce()
  if not extra:
break
  for el in extra:
adjust_with(el)
  calculate()

Is this second loop now more polymorphic as the first?


It's more confusing since you've changed the standard behavior of a 
standard type, which doesn't really have anything to do with 
polymorphism.  It's more confusing, if that's a benefit.


--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  In a cosmic setting, vast and old, beyond ordinary human
   understanding, we are a little lonely. -- Carl Sagan, 1934-1996
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-01 Thread Antoon Pardon
On 2008-08-01, Erik Max Francis [EMAIL PROTECTED] wrote:
 Antoon Pardon wrote:

 I now have the following question for people who argue that if x
 is more polymorphic. I could subclass list, so that instances
 of this new sequence would always behave as true, even if they are
 empty.  I could then rewrite my loop as follows:
 
 while 1:
   extra = produce()
   if not extra:
 break
   for el in extra:
 adjust_with(el)
   calculate()
 
 Is this second loop now more polymorphic as the first?

 It's more confusing since you've changed the standard behavior of a 
 standard type, which doesn't really have anything to do with 
 polymorphism.  It's more confusing, if that's a benefit.

So you accept my point that if x can be less polymorphic
and in fact can be more confusing than a more specific test.

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-01 Thread Matthew Fitzgibbons

Antoon Pardon wrote:

On 2008-08-01, Erik Max Francis [EMAIL PROTECTED] wrote:

Antoon Pardon wrote:


I now have the following question for people who argue that if x
is more polymorphic. I could subclass list, so that instances
of this new sequence would always behave as true, even if they are
empty.  I could then rewrite my loop as follows:

while 1:
  extra = produce()
  if not extra:
break
  for el in extra:
adjust_with(el)
  calculate()

Is this second loop now more polymorphic as the first?
It's more confusing since you've changed the standard behavior of a 
standard type, which doesn't really have anything to do with 
polymorphism.  It's more confusing, if that's a benefit.


So you accept my point that if x can be less polymorphic
and in fact can be more confusing than a more specific test.



I think your example is more related to a trap with polymorphism in 
general rather than an argument against 'is x' specifically. Any time 
you override a method, you have an opportunity to change the behavior in 
unexpected ways. Especially in languages like Python that don't do type 
checking. For example, you write a __cmp__ method like this:


class ReallyBadPractice(object):
def __cmp__(self, other):
return -cmp(self, other)

Of course any code that does comparisons on this class is going to 
behave unexpectedly!


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-01 Thread Matthew Fitzgibbons

Carl Banks wrote:

On Jul 31, 11:44 pm, Carl Banks [EMAIL PROTECTED] wrote:
[snip excellent explanation of why it's hard to for if x to be
extensively polymorphic]


By the way, one thing I forgot to mention is Matt Fitzgibbons' filter
example.

As I said, it's hard to write code that works for both numeric and
container types because they share so few methods.  However, sometimes
you don't know ahead of time what methods are used!  When you're doing
functional programming you might pass in a method that calls the
appropriate method, like so:

def apply_if_true(func,x):
if x:
func(x)


I find myself doing things like this surprisingly often. All you've done 
is move the decision as to what function is applied to x elsewhere. Like 
a factory, for example. I could see using something like this where func 
prepares object x to be inserted into a database, and you want to make 
sure x is meaningful first.


def add_to_db(prep_func, x):
if x:
entry = prep_func(x)
add_to_db(entry)

'if x' strikes me as better for this case because you might want to 
accept a non-empty list (or some other objects) but reject non-empty 
lists. 'if x is None' would not work. It still may be susceptible to the 
empty iterator problem, depending on what prep_func does.




The function f could use methods appropriate for ints when x is an
int, and for lists when x is an int.

I did downplay this, because frankly, not many programmers use
functional methods this extensively.  But one should also note that
you could pass in the test as well:

def apply_if_condition(func,cond,x):
if cond(x):
func(x)

Thus this usage of if x arguably could be considered replaceable
with a simple explicit test.  But in the interests of harmony I
didn't push the point, and it really would have been stretching the
spirit of what I was trying to prove.


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



Are you using cond to (a) determine is x is a suitable type to pass to 
func, or (b) whether or not to call func, based on some other 
characteristics of x?


If (a), I think using a condition is this way is a little goofy. Why not 
just allow func to decide is x is an acceptable argument?


(b) is not really what we've been discussing, so I assume not. I would 
seriously consider refactoring cond outside the function anyway.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-01 Thread Matthew Fitzgibbons

Matthew Fitzgibbons wrote:
'if x' strikes me as better for this case because you might want to 
accept a non-empty list (or some other objects) but reject non-empty 
lists. 'if x is None' would not work. It still may be susceptible to the 
empty iterator problem, depending on what prep_func does.


I mean reject empty lists. I need to be slower on hitting send.

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-01 Thread Antoon Pardon
On 2008-08-01, Matthew Fitzgibbons [EMAIL PROTECTED] wrote:
 Antoon Pardon wrote:
 On 2008-08-01, Erik Max Francis [EMAIL PROTECTED] wrote:
 Antoon Pardon wrote:

 I now have the following question for people who argue that if x
 is more polymorphic. I could subclass list, so that instances
 of this new sequence would always behave as true, even if they are
 empty.  I could then rewrite my loop as follows:

 while 1:
   extra = produce()
   if not extra:
 break
   for el in extra:
 adjust_with(el)
   calculate()

 Is this second loop now more polymorphic as the first?
 It's more confusing since you've changed the standard behavior of a 
 standard type, which doesn't really have anything to do with 
 polymorphism.  It's more confusing, if that's a benefit.
 
 So you accept my point that if x can be less polymorphic
 and in fact can be more confusing than a more specific test.
 

 I think your example is more related to a trap with polymorphism in 
 general rather than an argument against 'is x' specifically.

I didn't want to argue against if x. I just wanted to give a
counter point to the argument that if x is more polymorphic.

Whether more or less polymorphic is good or bad, depends on
what kind of polymophism and circumstances.

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-01 Thread Carl Banks
On Aug 1, 8:49 am, Matthew Fitzgibbons [EMAIL PROTECTED] wrote:
 Carl Banks wrote:
  On Jul 31, 11:44 pm, Carl Banks [EMAIL PROTECTED] wrote:
  [snip excellent explanation of why it's hard to for if x to be
  extensively polymorphic]

  By the way, one thing I forgot to mention is Matt Fitzgibbons' filter
  example.

  As I said, it's hard to write code that works for both numeric and
  container types because they share so few methods.  However, sometimes
  you don't know ahead of time what methods are used!  When you're doing
  functional programming you might pass in a method that calls the
  appropriate method, like so:

  def apply_if_true(func,x):
  if x:
  func(x)

 I find myself doing things like this surprisingly often. All you've done
 is move the decision as to what function is applied to x elsewhere. Like
 a factory, for example. I could see using something like this where func
 prepares object x to be inserted into a database, and you want to make
 sure x is meaningful first.

 def add_to_db(prep_func, x):
  if x:
  entry = prep_func(x)
  add_to_db(entry)

 'if x' strikes me as better for this case because you might want to
 accept a non-empty list (or some other objects) but reject non-empty
 lists. 'if x is None' would not work. It still may be susceptible to the
 empty iterator problem, depending on what prep_func does.

What if what you consider to be meaningful doesn't happen to
coincide with what Python considers to be something.  For instance,
what if being non-negative is what makes an integer meaningful?  You
can't use if x for that.  What if any list, including an empty one,
is meaningful, but you want to indicate the possibility of an
unmeaningful value by passing None?  You can't use if x for that.

So, you might address this issue by doing something like this:

def add_to_db(prep_func, is_meaningful, x):
 if is_meaningful(x):
 entry = prep_func(x)
 add_to_db(entry

But if you do that, what has the polymorphism of if x gained you?

The thing it gained for you before is not having to pass in a
condition: whether x was a sequence, number, or whatever, the same
condition could be used, and thus you avoided considerable
complexity.  But if you have to perform tests for which the implicit
boolean doesn't work, that complexity has to be added to the code
anyway.

That matters in the context of this discussion because it limits the
usefulness of the polymorphism of if x for this functional idiom:
if x only helps you if you have no need for tests that it can't
handle.

[snip]

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-01 Thread Terry Reedy

Nevertheless, I think this is probably the best example of the
enhanced polymorphism of if x yet.  I'm kind of surprised no one
came up with it.)


I think of Python code as 'generic' rather than 'polymorphic'.  I am not 
sure if that is a real difference or not, since I am a bit fuzzy on the 
meaning of 'polymorphic' in this context.


The generality of 'if x:' depends on the context.  If x is defined as a 
number by doc or previous code (or possibly even by subsequent code), 
then 'if x:' is equivalent to 'if x != 0:'.  At this point, it is a 
stylistic argument which to use.


But here is an example where 'if x:' is more generic.

def solve(a,b):
   'a and b such that b/a exists'
   if a:
  return a/b
   else:
  raise ValueError('a not invertible, cannot solve'

Now suppose we have a matrix class (2x2 for simplicity and realism).
Its __bool__ (3.0) method implements 'is non-singular'.  As written 
above, solve(mat,vec) works (with compatible mat and vec sizes), but it 
would not with 'if a != 0:'.


Of course, the issue goes away by not looking before the leap:

def solve(a,b):
return a/b
# let callers deal with exceptions
or
try:
   return a/b
except...
  # raise customized error


In general, the ability to take advantage of if x polymorphism
across numeric, container, and other types depends on the something/
nothing dichotomy to be applicable.


Numbers and sequences are both sortable with the same algorithm if it is 
written to be generic.  However, 0 is nothing special when sorting, so 
'if x:' would not be used.


All collections are (or should be) iterable.  But a boolean test is not 
part of the current iteration protocol.  One might want to test whether 
the iterable starts with anything before setting things up, but that 
either exclude most iterators or requires wrapping them in a lookahead 
class with a __bool__ method.


In general, asking code to apply across numeric, container, and other 
classes is asking too much.  Python code can be generic only within 
protocol/interface categories such as number-like, sortable, and 
iterable.  But making tests too specific can unnecessarily prevent even 
that.


 Something versus nothing is a useless concept most of the time, but
 occasionally finds use in human interaction cases such as printing.

It is sometimes useful within categories of classes, as in my solve example.

Terry Jan Reedy

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-01 Thread Matthew Fitzgibbons

Carl Banks wrote:

On Aug 1, 8:49 am, Matthew Fitzgibbons [EMAIL PROTECTED] wrote:

Carl Banks wrote:

On Jul 31, 11:44 pm, Carl Banks [EMAIL PROTECTED] wrote:
[snip excellent explanation of why it's hard to for if x to be
extensively polymorphic]
By the way, one thing I forgot to mention is Matt Fitzgibbons' filter
example.
As I said, it's hard to write code that works for both numeric and
container types because they share so few methods.  However, sometimes
you don't know ahead of time what methods are used!  When you're doing
functional programming you might pass in a method that calls the
appropriate method, like so:
def apply_if_true(func,x):
if x:
func(x)

I find myself doing things like this surprisingly often. All you've done
is move the decision as to what function is applied to x elsewhere. Like
a factory, for example. I could see using something like this where func
prepares object x to be inserted into a database, and you want to make
sure x is meaningful first.

def add_to_db(prep_func, x):
 if x:
 entry = prep_func(x)
 add_to_db(entry)

'if x' strikes me as better for this case because you might want to
accept a non-empty list (or some other objects) but reject non-empty
lists. 'if x is None' would not work. It still may be susceptible to the
empty iterator problem, depending on what prep_func does.


What if what you consider to be meaningful doesn't happen to
coincide with what Python considers to be something.  For instance,
what if being non-negative is what makes an integer meaningful?  You
can't use if x for that.  What if any list, including an empty one,
is meaningful, but you want to indicate the possibility of an
unmeaningful value by passing None?  You can't use if x for that.

So, you might address this issue by doing something like this:

def add_to_db(prep_func, is_meaningful, x):
 if is_meaningful(x):
 entry = prep_func(x)
 add_to_db(entry

But if you do that, what has the polymorphism of if x gained you?

The thing it gained for you before is not having to pass in a
condition: whether x was a sequence, number, or whatever, the same
condition could be used, and thus you avoided considerable
complexity.  But if you have to perform tests for which the implicit
boolean doesn't work, that complexity has to be added to the code
anyway.


Of course. If a chunk of code already does what you want it to, then you 
can use it. Otherwise you have to do something different. I was just 
pointing out that 'if x' often does what I want it to. Sometimes it 
doesn't, so I do something different.




That matters in the context of this discussion because it limits the
usefulness of the polymorphism of if x for this functional idiom:
if x only helps you if you have no need for tests that it can't
handle.

[snip]

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



By this argument, all code is limiting. Obviously, no code can do what 
it can't.


We're not getting anywhere; it's past time to kill this one off.

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-01 Thread Carl Banks
On Aug 1, 3:36 pm, Terry Reedy [EMAIL PROTECTED] wrote:
  Nevertheless, I think this is probably the best example of the
  enhanced polymorphism of if x yet.  I'm kind of surprised no one
  came up with it.)

 I think of Python code as 'generic' rather than 'polymorphic'.  I am not
 sure if that is a real difference or not, since I am a bit fuzzy on the
 meaning of 'polymorphic' in this context.

 The generality of 'if x:' depends on the context.  If x is defined as a
 number by doc or previous code (or possibly even by subsequent code),
 then 'if x:' is equivalent to 'if x != 0:'.  At this point, it is a
 stylistic argument which to use.

 But here is an example where 'if x:' is more generic.

 def solve(a,b):
 'a and b such that b/a exists'
 if a:
return a/b
 else:
raise ValueError('a not invertible, cannot solve'

 Now suppose we have a matrix class (2x2 for simplicity and realism).
 Its __bool__ (3.0) method implements 'is non-singular'.  As written
 above, solve(mat,vec) works (with compatible mat and vec sizes), but it
 would not with 'if a != 0:'.

I see what you're saying, even though this example turns out to be
pretty bad in practice.

(Practically speaking, you hardly ever write code for both matrices
and scalars, because the optimal way for matrices would be convoluted
and opaque for scalars, though scalars can sometimes be fed into
matrix code as a degenerate case.  Also, checking the condition of the
matrix by calculating and comparing the determinant to zero is like
comparing float equality without a tolerance, only much, much worse.)

But instead of a matrix, take a vector (which has a better chance of
being used in code designed for scalars) and define a zero-length
vector as false, and that could be a good example.


 In general, asking code to apply across numeric, container, and other
 classes is asking too much.  Python code can be generic only within
 protocol/interface categories such as number-like, sortable, and
 iterable.  But making tests too specific can unnecessarily prevent even
 that.

At some point we have to throw our hands up and realize that if we're
working with custom classes with varying degrees of nonconformance,
there is nothing we can do that's safe.


   Something versus nothing is a useless concept most of the time, but
   occasionally finds use in human interaction cases such as printing.

 It is sometimes useful within categories of classes, as in my solve example.

I'm going to say no.

Let's take your matrix example: you defined singularity to be false,
but singularity can't reasonably be mapped to the concept of nothing.
For nothing I would think you'd want a 0x0 matrix.  Something vs
nothing also implies that all objects should have a boolean value.
So, assuming boolean is connected to a matrices singularity, what
should be the boolean value of non-square matrices?

No, I'm going to have to disagree very strongly with this.
Nonzeroness is useful.  Emptiness is useful.  Singularity a kind of
useful.  Nothing and something are vague, ill-defined, ad hoc concepts
that mean nothing to a computer.  Have you ever seen an algorithm that
says if x is something?

Something and nothing do seem to come into play occasionally in that,
when interacting with humans (be it the user or programmer), it
sometimes--not nearly always--makes sense to treat nonzero and empty
in the same way.  But there's no particular reason to apply the
concepts of something and nothing beyond this pragmatic use.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-01 Thread Carl Banks
On Aug 1, 4:45 pm, Carl Banks [EMAIL PROTECTED] wrote:
 On Aug 1, 3:36 pm, Terry Reedy [EMAIL PROTECTED] wrote:



   Nevertheless, I think this is probably the best example of the
   enhanced polymorphism of if x yet.  I'm kind of surprised no one
   came up with it.)

  I think of Python code as 'generic' rather than 'polymorphic'.  I am not
  sure if that is a real difference or not, since I am a bit fuzzy on the
  meaning of 'polymorphic' in this context.

  The generality of 'if x:' depends on the context.  If x is defined as a
  number by doc or previous code (or possibly even by subsequent code),
  then 'if x:' is equivalent to 'if x != 0:'.  At this point, it is a
  stylistic argument which to use.

  But here is an example where 'if x:' is more generic.

  def solve(a,b):
  'a and b such that b/a exists'
  if a:
 return a/b
  else:
 raise ValueError('a not invertible, cannot solve'

  Now suppose we have a matrix class (2x2 for simplicity and realism).
  Its __bool__ (3.0) method implements 'is non-singular'.  As written
  above, solve(mat,vec) works (with compatible mat and vec sizes), but it
  would not with 'if a != 0:'.

 I see what you're saying, even though this example turns out to be
 pretty bad in practice.

 (Practically speaking, you hardly ever write code for both matrices
 and scalars, because the optimal way for matrices would be convoluted
 and opaque for scalars, though scalars can sometimes be fed into
 matrix code as a degenerate case.  Also, checking the condition of the
 matrix by calculating and comparing the determinant to zero is like
 comparing float equality without a tolerance, only much, much worse.)

 But instead of a matrix, take a vector (which has a better chance of
 being used in code designed for scalars) and define a zero-length
 vector as false, and that could be a good example.

  In general, asking code to apply across numeric, container, and other
  classes is asking too much.  Python code can be generic only within
  protocol/interface categories such as number-like, sortable, and
  iterable.  But making tests too specific can unnecessarily prevent even
  that.

 At some point we have to throw our hands up and realize that if we're
 working with custom classes with varying degrees of nonconformance,
 there is nothing we can do that's safe.

Something versus nothing is a useless concept most of the time, but
occasionally finds use in human interaction cases such as printing.

  It is sometimes useful within categories of classes, as in my solve example.

 I'm going to say no.

 Let's take your matrix example: you defined singularity to be false,
 but singularity can't reasonably be mapped to the concept of nothing.
 For nothing I would think you'd want a 0x0 matrix.  Something vs
 nothing also implies that all objects should have a boolean value.
 So, assuming boolean is connected to a matrices singularity, what
 should be the boolean value of non-square matrices?

 No, I'm going to have to disagree very strongly with this.
 Nonzeroness is useful.  Emptiness is useful.  Singularity a kind of
 useful.  Nothing and something are vague, ill-defined, ad hoc concepts
 that mean nothing to a computer.  Have you ever seen an algorithm that
 says if x is something?

 Something and nothing do seem to come into play occasionally in that,
 when interacting with humans (be it the user or programmer), it
 sometimes--not nearly always--makes sense to treat nonzero and empty
 in the same way.  But there's no particular reason to apply the
 concepts of something and nothing beyond this pragmatic use.

 Carl Banks

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-08-01 Thread Carl Banks
On Aug 1, 4:45 pm, Carl Banks [EMAIL PROTECTED] wrote:
 On Aug 1, 3:36 pm, Terry Reedy [EMAIL PROTECTED] wrote:
  In general, asking code to apply across numeric, container, and other
  classes is asking too much.  Python code can be generic only within
  protocol/interface categories such as number-like, sortable, and
  iterable.  But making tests too specific can unnecessarily prevent even
  that.

 At some point we have to throw our hands up and realize that if we're
 working with custom classes with varying degrees of nonconformance,
 there is nothing we can do that's safe.

And I want to make clear I'm not trying to downplay your example
here.  The example you gave me definitely fits the criteria of being a
useful if x that can't be replaced by a simple explicit test, at
least after my alteration to a vector example.

It's a concern when you write code that breaks realistic custom
classes, but really concerning when it breaks built-in classes.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Russ P.
On Jul 30, 10:43 pm, Erik Max Francis [EMAIL PROTECTED] wrote:
 Russ P. wrote:
  On Jul 30, 9:27 pm, Erik Max Francis [EMAIL PROTECTED] wrote:
  You're sure going on about a distinction without a difference for a guy
  who childishly likes to call other people names.  A reasonable person
  would have long ago moved on instead of blaming others for not
  immediately intuiting your thoughts, rather than straightforwardly
  reading your words.  Which, by the way, includes at least three people
  other than myself.

  But I'll bet the mindless namecalling is really working out for you.
  Go, team, go!

  You earned the childish name calling by acting like a child -- with
  your petty little game of trying to show that I don't understand a
  basic concept in Python. As I said, your initial misunderstanding,
  while silly, was at least forgivable. But your insistence on repeating
  it time after time is not. It is truly pathetic.

 Sis, boom, rah rah rah!

 You're kind of skipping over the point where three other people had the
 same misunderstanding about your original statement and correction, so

Another whopper, but who's counting?

 maybe the reader is not the problem but rather the writer, but hey,
 don't let that get in the way of a good public shitfit.

 You're winning!

And you're a professional of some sort? Man, I can't even imagine
working in an environment with people like you. I guess I'm pretty
lucky to work with real professionals who don't play petty little
games like the one you played here -- and are still playing. Go ahead,
have the last word, loser -- then get lost.

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Iain King
On Jul 31, 7:08 am, Russ P. [EMAIL PROTECTED] wrote:
 On Jul 30, 10:43 pm, Erik Max Francis [EMAIL PROTECTED] wrote:



  Russ P. wrote:
   On Jul 30, 9:27 pm, Erik Max Francis [EMAIL PROTECTED] wrote:
   You're sure going on about a distinction without a difference for a guy
   who childishly likes to call other people names.  A reasonable person
   would have long ago moved on instead of blaming others for not
   immediately intuiting your thoughts, rather than straightforwardly
   reading your words.  Which, by the way, includes at least three people
   other than myself.

   But I'll bet the mindless namecalling is really working out for you.
   Go, team, go!

   You earned the childish name calling by acting like a child -- with
   your petty little game of trying to show that I don't understand a
   basic concept in Python. As I said, your initial misunderstanding,
   while silly, was at least forgivable. But your insistence on repeating
   it time after time is not. It is truly pathetic.

  Sis, boom, rah rah rah!

  You're kind of skipping over the point where three other people had the
  same misunderstanding about your original statement and correction, so

 Another whopper, but who's counting?

  maybe the reader is not the problem but rather the writer, but hey,
  don't let that get in the way of a good public shitfit.

  You're winning!

 And you're a professional of some sort? Man, I can't even imagine
 working in an environment with people like you. I guess I'm pretty
 lucky to work with real professionals who don't play petty little
 games like the one you played here -- and are still playing. Go ahead,
 have the last word, loser -- then get lost.

You understand this is usenet, right?  Where we can all read the
entire thread?  So trying to spin the situation just doesn't work?
Just checking...

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Chris Mellon
On Tue, Jul 29, 2008 at 3:37 AM, Carl Banks [EMAIL PROTECTED] wrote:
 On Jul 28, 8:15 pm, Steven D'Aprano [EMAIL PROTECTED]
 cybersource.com.au wrote:
 On Mon, 28 Jul 2008 13:22:37 -0700, Carl Banks wrote:
  On Jul 28, 10:00 am, Steven D'Aprano [EMAIL PROTECTED]
  cybersource.com.au wrote:
  Cutting to the crux of the discussion...

  On Sun, 27 Jul 2008 23:45:26 -0700, Carl Banks wrote:
   I want something where if x will do but a simple explicit test
   won't.

  Explicit tests aren't simple unless you know what type x is. If x could
  be of any type, you can't write a simple test. Does x have a length? Is
  it a number? Maybe it's a fixed-length circular length, and the length
  is non-zero even when it's empty? Who knows? How many cases do you need
  to consider?

  Use case, please.  I'm asking for code, not arguments.  Please give me a
  piece of code where you can write if x that works but a simple
  explicit test won't.

 I gave you a piece of code, actual code from one of my own projects. If
 you wouldn't accept that evidence then, why would you accept it now?

 I would accept as evidence something that satisfies my criteria,
 which your example did not: it could have easily (and more robustly)
 been written with a simple explicit test.  I am looking for one that
 can't.

 You keep bringing up this notion of more complex with no benefit,
 which I'm simply not interested in talking about that at this time,
 and I won't respond to any of your points.  I am seeking the answer to
 one question: whether if x can usefully do something a simple
 explicit test can't.  Everyone already knows that if x requires
 fewer keystrokes and parses to fewer nodes.


I'm really not sure where you're going with this or what you're trying
to prove. if x is a duck-type test for a boolean value. Obviously if
you know the type and want a more *specific* test, then you can use an
explicit one. Any time you don't know or don't care about a more
specific type than something which probably is boolean true, or any
time where you know the boolean semantics of the type and want to drop
some typing, you can use if x. The more specific test is what you'd
use if you want more specific results. What's complicated about this
idea?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Matthew Fitzgibbons

Steven D'Aprano wrote:

On Wed, 30 Jul 2008 09:23:05 -0600, Matthew Fitzgibbons wrote:


If you're expecting a list (and only a list)
then your point makes sense. 'if x' can get you into trouble if you
_don't_ want its polymorphism.


if x is hardly unique in that way. If you're expecting a list, and only 
a list, len(x) != 0 will get you in trouble if somebody passes a string 
or a dictionary. I don't see any reason why we should single out if x 
as dangerous in the face of invalid types. With the exception of the is 
and is not operators, nothing in Python is guaranteed to work with any 
imaginable object. Even print can fail, if the object's __str__ method 
raises an exception.


 

Although, if my function is expecting a list, my preference is to do:

if not isinstance(x, list):
 raise SomeMeaningfulException()
# do stuff with the list

I put my type checking at the top of the function, so readers can
reference it easily.


And thus you break duck-typing and upset anybody who wants to pass a 
sequence that doesn't inherit directly from list.


There are other (and arguably better, although more labour-intensive) 
techniques for defensive programming that don't break duck-typing. You 
can google for Look Before You Leap and Easier To Ask Forgiveness Than 
Permission for more information. Alex Martelli has a fine recipe in the 
Python Cookbook -- search for the recipe Checking if an object has the 
necessary attributes.


But in a nutshell, here's a toy example:

def spam(seq):
try:
seq.append
seq.extend
seq[0] = seq[0]
except Exception:
raise TypeError(argument isn't sufficiently sequence-like)
# No exceptions expected from here on
seq.append(seq[0])
seq.extend([1,2,3])
seq[0] = spam






Yes, I know it breaks duck typing, which is why I do it only very 
rarely, and never with e.g. sequence types. If I use ifinstance for type 
checking, it's because I need some _very_ specific class, almost always 
one that I wrote. My more usual use case for ifinstance is to figure out 
how to handle a particular object using introspection.


That said, your example is still helpful. It's a good approach, and I 
should use it more often. Although I'd also lean toward hasattr and 
iscallable and ordinary ifs instead of the try ... except where 
possible. Depending on what you put in the try ... except, you risk 
masking legit exceptions.


Ahhh, Programing. Where no rule of thumb seems to last five minutes.

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Matthew Fitzgibbons

Steven D'Aprano wrote:

On Wed, 30 Jul 2008 09:23:05 -0600, Matthew Fitzgibbons wrote:


If you're expecting a list (and only a list)
then your point makes sense. 'if x' can get you into trouble if you
_don't_ want its polymorphism.


if x is hardly unique in that way. If you're expecting a list, and only 
a list, len(x) != 0 will get you in trouble if somebody passes a string 
or a dictionary. I don't see any reason why we should single out if x 
as dangerous in the face of invalid types. With the exception of the is 
and is not operators, nothing in Python is guaranteed to work with any 
imaginable object. Even print can fail, if the object's __str__ method 
raises an exception.


Forgot respond to this point. I heartily agree. :) I singled out 'if x' 
only because that's the specific example under scrutiny. I think you and 
I are pretty much in agreement.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Matthew Fitzgibbons

Matthew Fitzgibbons wrote:

Steven D'Aprano wrote:

On Wed, 30 Jul 2008 09:23:05 -0600, Matthew Fitzgibbons wrote:


If you're expecting a list (and only a list)
then your point makes sense. 'if x' can get you into trouble if you
_don't_ want its polymorphism.


if x is hardly unique in that way. If you're expecting a list, and 
only a list, len(x) != 0 will get you in trouble if somebody passes 
a string or a dictionary. I don't see any reason why we should single 
out if x as dangerous in the face of invalid types. With the 
exception of the is and is not operators, nothing in Python is 
guaranteed to work with any imaginable object. Even print can fail, if 
the object's __str__ method raises an exception.


 

Although, if my function is expecting a list, my preference is to do:

if not isinstance(x, list):
 raise SomeMeaningfulException()
# do stuff with the list

I put my type checking at the top of the function, so readers can
reference it easily.


And thus you break duck-typing and upset anybody who wants to pass a 
sequence that doesn't inherit directly from list.


There are other (and arguably better, although more labour-intensive) 
techniques for defensive programming that don't break duck-typing. You 
can google for Look Before You Leap and Easier To Ask Forgiveness Than 
Permission for more information. Alex Martelli has a fine recipe in 
the Python Cookbook -- search for the recipe Checking if an object 
has the necessary attributes.


But in a nutshell, here's a toy example:

def spam(seq):
try:
seq.append
seq.extend
seq[0] = seq[0]
except Exception:
raise TypeError(argument isn't sufficiently sequence-like)
# No exceptions expected from here on
seq.append(seq[0])
seq.extend([1,2,3])
seq[0] = spam






Yes, I know it breaks duck typing, which is why I do it only very 
rarely, and never with e.g. sequence types. If I use ifinstance for type 
checking, it's because I need some _very_ specific class, almost always 
one that I wrote. My more usual use case for ifinstance is to figure out 
how to handle a particular object using introspection.


That said, your example is still helpful. It's a good approach, and I 
should use it more often. Although I'd also lean toward hasattr and 
iscallable and ordinary ifs instead of the try ... except where 
possible. Depending on what you put in the try ... except, you risk 
masking legit exceptions.


Ahhh, Programing. Where no rule of thumb seems to last five minutes.

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



Where by ifinstance I mean isinstance and by iscallable I mean callable.

*hides*

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Matthew Woodcraft
Steven D'Aprano wrote:
On Wed, 30 Jul 2008 20:55:03 +0100, Matthew Woodcraft wrote:

 On the other hand, iterators provide a clear example of problems with
 if x: __nonzero__ for iterators (in general) returns True even if they
 are 'empty'.

 How do you propose telling whether an iterator is empty?
 That's a generic problem with any sort of lazy function. You don't know
 if it has finished unless you try grabbing data from it.

Of course.

The point is that if you tell people that if x is the standard way to
check for emptiness, and also support a general principle along the
lines of write your function using the interfaces you expect, and call
it using the object you have, you should expect to end up with bugs of
this sort.


 For example, this function (which attempts to avoid making an expensive
 call when not necessary) is buggy, but easy to write if you've been
 taught that if x will work with any kind of object.

 def frob(widgets, power):
 if widgets:
 frobber = Frobber(power) # expensive call
 for widget in widgets:
 frobber.frob(widget)

 AFAIK there's no great solution to this problem. It's inherent in the way
 lazy functions work. Certainly you can't replace the call to if widgets
 with if len(widgets), because iterators don't have a length.

I'm not a fan of len() for testing emptiness. But it would have been
better in this case, because it would have converted a hard-to-find
performance bug into an obvious exception.


However, there is a good (but not great) solution:

def frob(widgets, power):
widgets = iter(widgets)  # in case widgets is a sequence
try:
first = widgets.next()
except StopIteration:
# empty iterator, nothing to do
return None
frobber = Frobber(power) # expensive call
frobber.frob(widget)
for widget in widgets:
frobber.frob(widget)

I would use the following low-tech way:

def frob(widgets, power):
frobber = None
for widget in widgets:
if frobber is None:
frobber = Frobber(power)
frobber.frob(widget)

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Steven D'Aprano
On Thu, 31 Jul 2008 22:01:48 +0100, Matthew Woodcraft wrote:

 Steven D'Aprano wrote:
On Wed, 30 Jul 2008 20:55:03 +0100, Matthew Woodcraft wrote:
 
 On the other hand, iterators provide a clear example of problems with
 if x: __nonzero__ for iterators (in general) returns True even if
 they are 'empty'.
 
 How do you propose telling whether an iterator is empty? That's a
 generic problem with any sort of lazy function. You don't know if it
 has finished unless you try grabbing data from it.
 
 Of course.
 
 The point is that if you tell people that if x is the standard way to
 check for emptiness, and also support a general principle along the
 lines of write your function using the interfaces you expect, and call
 it using the object you have, you should expect to end up with bugs of
 this sort.

I'm not sure that an occasional performance hit justifies calling it a 
bug. I suppose you might come up with a scenario or two where it really 
is a problem, but then I'm also free to imagine scenarios where calling 
len(obj) takes a massive performance hit, or has irreversible side 
effects.


 For example, this function (which attempts to avoid making an
 expensive call when not necessary) is buggy, but easy to write if
 you've been taught that if x will work with any kind of object.

 def frob(widgets, power):
 if widgets:
 frobber = Frobber(power) # expensive call
 for widget in widgets:
 frobber.frob(widget)

But note that the code still does the right thing even if widgets is 
empty. The only problem is that it needlessly calls Frobber. Frankly, 
that would have to be *really* expensive before I would even bother using 
the more complicated code. This is a good example of premature 
optimization.

 
 AFAIK there's no great solution to this problem. It's inherent in the
 way lazy functions work. Certainly you can't replace the call to if
 widgets with if len(widgets), because iterators don't have a length.
 
 I'm not a fan of len() for testing emptiness. But it would have been
 better in this case, because it would have converted a hard-to-find
 performance bug into an obvious exception.

At the cost of wrongly raising a exception for perfectly good arguments, 
namely non-empty iterators.



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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Matthew Woodcraft
Steven D'Aprano wrote:
On Thu, 31 Jul 2008 22:01:48 +0100, Matthew Woodcraft wrote:
 The point is that if you tell people that if x is the standard way to
 check for emptiness, and also support a general principle along the
 lines of write your function using the interfaces you expect, and call
 it using the object you have, you should expect to end up with bugs of
 this sort.

 I'm not sure that an occasional performance hit justifies calling it a
 bug. I suppose you might come up with a scenario or two where it really
 is a problem, but then I'm also free to imagine scenarios where calling
 len(obj) takes a massive performance hit, or has irreversible side
 effects.

Of course performance problems can be bugs! And it was explicit in my
example that this was supposed to be such a case.

But here, have an example where it's a non-performance bug:

def load_widgets(self, widgets):
if not widgets:
raise ValueError(no widgets specified)
self._prepare_for_widgets()
for widget in widgets:
self._load_widget(widget)
self._is_widgetty = True

This way you can end up with an object in an invalid state.


 I'm not a fan of len() for testing emptiness. But it would have been
 better in this case, because it would have converted a hard-to-find
 performance bug into an obvious exception.

 At the cost of wrongly raising a exception for perfectly good arguments,
 namely non-empty iterators.

Sure, which will be fixed when the code passing an iterator is first
tested, whether the iterator is empty or not. It's the errors which pass
silently that are most dangerous.


As I said, I'm not a fan of len() for testing emptiness. But if x
isn't good either. Often I end up rearranging things so I can get rid of
the explicit test altogether, but there can be a cost in readability.

I think any Python-like language would be better off with an explicit
way of asking 'is this container empty?'.

-M-

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Carl Banks
On Jul 31, 1:27 pm, Chris Mellon [EMAIL PROTECTED] wrote:
 I'm really not sure where you're going with this or what you're trying
 to prove. if x is a duck-type test for a boolean value. Obviously if
 you know the type and want a more *specific* test, then you can use an
 explicit one. Any time you don't know or don't care about a more
 specific type than something which probably is boolean true, or any
 time where you know the boolean semantics of the type and want to drop
 some typing, you can use if x. The more specific test is what you'd
 use if you want more specific results. What's complicated about this
 idea?

Many people trumpet that if x makes your code more polymorphic
whenever this comes up--in fact you just repeated the claim--without
ever considering how rarely this more extensive polymorphism comes up
in practice.   I was calling them out to say prove to me that it
actually happens.

I believe it's very rare not to know enough about the expected type
that explicit tests won't work.  We've uncovered a few examples of it
in this thread, but IMO we haven't uncovered any sort of broad, wide-
ranging use cases.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Carl Banks
On Jul 31, 12:13 am, Ethan Furman [EMAIL PROTECTED] wrote:
 Carl Banks wrote:
  So I stand by the point I was trying to make: for your average day-to-
  day programming, the main benefit of if x is to save keystrokes.  It
  doesn't help your code become more polymophic in practice.  A little
  more polymorphic, yes.  A lot, no.

 Hmmm... well, I see your point.  Unfortunately, even though it feels
 incorrect to me, I do not (yet) have the breadth and depth of Python
 experience to come up with an example that would display such exquisite
 polymorphism.  It also seems to me that such an example would be
 non-trivial in nature.

Wrong on both counts.  Let me give you a hint.

Take integers and lists.  Count how many methods the two types have in
common.  By my reckoning, they are:

__add__, __iadd__, __mul__, _imul__, __str__, __repr__, and
__nonzero__.

Also there are __getattribute__ and __setattr__, but lists and ints
share no common attributes.  I don't think ints have any at all aside
from the special methods.

What this means is: any code that can work for both ints and lists
must use only these methods (this is not quite correct, but mostly
is).  That eliminates probably 99.9% of code right off the bat.

Then you have to consider that some code that does use only these
attributes does something useful only for either ints or lists, not
both.  Take this simple example:

def foil(a,b,c,d):
return a*b + a*d + b*c + b*d

This code works if a and c are both ints, or are both lists (while b
and d would have to be ints).  It does something useful for ints and
other numeric types, but does it do anything useful for lists?

Third, there are cases where you have code that works for both ints
and lists, that does do something useful for both, but it makes no
sense to apply if x to it.

def print_if_true(x):
if x:
print x

This little piece of code might actually come in handy here and there,
but would it end up being used for numeric types a whole lot?  It
seems like if you have an empty list you might reasonably want to
print nothing at all, but when you have a zero integer you usually
want to print the zero.

(However, you might reasonably want to print some object unless it's
None.  You could then use this one function to handle that case as
well as the case with empty lists, instead of defining two functions,
like so:

print_if_not_empty(x):
if len(x)!=0:
print x

print_if_not_None(x):
if x is not None:
print x

But wait!  What if you had a value that could be either an integer or
None?  You can't use the if x variant because x could be False.  So
you'd have to define the if x is not None variant anyway.  I might
use the if x variant in throwaway scripts, but for anything
production I would prefer the explicit variants, partially because, as
shown above, even when if x does rear it's polymoprhic head, it
doesn't necessarily buy you much.

Nevertheless, I think this is probably the best example of the
enhanced polymorphism of if x yet.  I'm kind of surprised no one
came up with it.)

In general, the ability to take advantage of if x polymorphism
across numeric, container, and other types depends on the something/
nothing dichotomy to be applicable.  Something versus nothing is a
useless concept most of the time, but occasionally finds use in human
interaction cases such as printing.

So there you have it.  This is why I didn't expect anyone to come up
with a good example: you just don't have a lot to work with.



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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Carl Banks
On Jul 30, 10:05 pm, Erik Max Francis [EMAIL PROTECTED] wrote:
 Russ P. wrote:
  On Jul 30, 1:07 am, Erik Max Francis [EMAIL PROTECTED] wrote:
  Russ P. wrote:
  Oh, Lordy. I understand perfectly well how boolean tests, __len__, and
  __nonzero__ work in Python. It's very basic stuff. You can quit
  patronizing me (and Carl too, I'm sure).
  You suggested a syntax for testing non-emptiness (`x is not empty`)
  which indicated a profound misunderstanding of what the `is` operator does.

  You then acknowledged that there might be a problem because of the
  implication if the `is` operator and weren't sure whether it would work
  or not:

  Oh, my. I wrote something like, It would sure be nice to be able to
  write

  if x is not empty:

  because it reads like natural language. Immediately after I posted it,
  I thought, oh, I'll bet some idiot takes that as a serious proposal.
  Sure enough, some idiot did just that almost immediately.

 Yes, all people are idiots for reading what you wrote, reading your
 later realization that it was wrong, and taking both at face value.
 I'll be sure never to make that mistake again!

I thought it was obvious that he was paraphrasing.  I also think that,
among the people who took it literally, those who are not an ass would
have accepted his explanation that he was paraphrasing it and moved
on, rather than rubbing it in.

If you recall, I agreed with his statement.  Would you like to claim
that I don't understand the fundamentals of Python?


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Carl Banks
On Jul 31, 11:44 pm, Carl Banks [EMAIL PROTECTED] wrote:
[snip excellent explanation of why it's hard to for if x to be
extensively polymorphic]


By the way, one thing I forgot to mention is Matt Fitzgibbons' filter
example.

As I said, it's hard to write code that works for both numeric and
container types because they share so few methods.  However, sometimes
you don't know ahead of time what methods are used!  When you're doing
functional programming you might pass in a method that calls the
appropriate method, like so:

def apply_if_true(func,x):
if x:
func(x)

The function f could use methods appropriate for ints when x is an
int, and for lists when x is an int.

I did downplay this, because frankly, not many programmers use
functional methods this extensively.  But one should also note that
you could pass in the test as well:

def apply_if_condition(func,cond,x):
if cond(x):
func(x)

Thus this usage of if x arguably could be considered replaceable
with a simple explicit test.  But in the interests of harmony I
didn't push the point, and it really would have been stretching the
spirit of what I was trying to prove.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-31 Thread Erik Max Francis

Carl Banks wrote:


If you recall, I agreed with his statement.  Would you like to claim
that I don't understand the fundamentals of Python?


Since you've invented this connection out of nowhere, not particularly. 
 I've never said anything about _anyone_ not understanding the 
fundamentals of Python, so you're just trying to make up controversy here.


--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  We all breathe the same air. We all cherish our children's future.
   And we are all mortal. -- John F. Kennedy
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Russ P.
On Jul 29, 10:33 pm, Carl Banks [EMAIL PROTECTED] wrote:
 On Jul 30, 1:15 am, Russ P. [EMAIL PROTECTED] wrote:

  Having said that, it would sure be nice to be able to write

  if myList is not empty:

  instead of

  if len(myList) != 0:

 I can agree with this.

But I guess that could only work if there were only one empty list
that represents all empty lists (as there is only one actual None).
I don't know if that makes sense or not.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Erik Max Francis

Carl Banks wrote:


Bull.  This is a request, that, if satisfied, would prove that if x
is more polymorphic than a simple explicit test.  I posed the question
precisely to see if anyone could come up with a use case that shows
this benefit of if x.


Except you're the only one who's not convinced of it, and it's your 
test, and your rules.  So who cares?



if x _is_ a completely simple
test.  Simpler, in fact, than the ones you were advocating.


It's not explicit.


It's not explicit enough for you, yes, that much is obvious.  Contests 
that rely on mind-reading aren't too much fun for anyone involved.



I've explained why I doubt that it helps polymorphism that much: you
almost never see code for which an integer and list both work, so
having the ability to spell a test the same way for both types isn't
useful.  If you claim that if x does help polymorphism, please tell
me what's wrong with the above analysis.


It helps polymorphism for types other that (say) numerics and sequences. 
 There are plenty of container objects for which an is this 
non-empty? test is far simpler a how many objects are in this 
container? test, and several examples have already been given -- as in, 
O(1) vs. O(n) complexity or worse.  You've seem to have even 
acknowledged this, but are still insisting on continuing the challenge. 
 You're drawing an artificial line in the sand to compare length 
computation to a more specialized non-emptiness test.  (And, as I've 
pointed out, what happens if you're dealing with a sequence type that 
_doesn't_ have a length?  Then certainly `len(x) != 0` is nonsensical.)


Perhaps in the particular use case you're thinking of (numeric types vs. 
container types), there aren't any good examples.  But who cares? 
Polymorphism applies in more than just this one special case.  You're 
setting up a challenge that isn't very interesting, and which is rigged 
so that no one can win because you're the one who.  So, what's the point?


--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  Can I be your friend / 'Till the end
   -- India Arie
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Erik Max Francis

Russ P. wrote:


All this discussion about if x has me wondering. I use it all the
time because a fully explicit test just seems redundant. But maybe it
does have some value in terms of readability and type checking. After
all, it is possible to forget whether something is a number or a list.

Having said that, it would sure be nice to be able to write

if myList is not empty:


I sure hope that's a joke.  `x is not y` means something quite different.

--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  The doors of Heaven and Hell are adjacent and identical.
   -- Nikos Kazantzakis
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Erik Max Francis

Carl Banks wrote:


On Jul 30, 1:15 am, Russ P. [EMAIL PROTECTED] wrote:

All this discussion about if x has me wondering. I use it all the
time because a fully explicit test just seems redundant. But maybe it
does have some value in terms of readability and type checking. After
all, it is possible to forget whether something is a number or a list.


IMO, the only time I think if x is really dangerous is if you are
using if x instead of if x is None to distinguish between None and
a type that can have false values.


Well, that would be an exceptionally bad way to test for None-ness, 
since None is false.  The test would never succeed.



Having said that, it would sure be nice to be able to write

if myList is not empty:

instead of

if len(myList) != 0:


I can agree with this.


I'm getting this sneaking suspicion that you guys are all putting us on.

--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  The doors of Heaven and Hell are adjacent and identical.
   -- Nikos Kazantzakis
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Erik Max Francis

Russ P. wrote:


On Jul 29, 10:33 pm, Carl Banks [EMAIL PROTECTED] wrote:

On Jul 30, 1:15 am, Russ P. [EMAIL PROTECTED] wrote:



Having said that, it would sure be nice to be able to write
if myList is not empty:
instead of
if len(myList) != 0:

I can agree with this.


But I guess that could only work if there were only one empty list
that represents all empty lists (as there is only one actual None).
I don't know if that makes sense or not.


It really doesn't, since it presumably wouldn't apply to just list 
types.  There are plenty of other sequence types:  such as tuples, 
strings, or even arbitrary custom types.  Emptiness is a test for the 
value of an object, not a test for whether it is identical to another 
object, so this is a very misleading of the `is` operator, bordering on 
abuse.


This syntax would make far less sense than the existing Boolean test.

--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  The doors of Heaven and Hell are adjacent and identical.
   -- Nikos Kazantzakis
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Russ P.
On Jul 29, 11:09 pm, Erik Max Francis [EMAIL PROTECTED] wrote:

 I'm getting this sneaking suspicion that you guys are all putting us on.

As I said in an earlier post, I realize that this would only work if
there were only one copy of empty (as there is only one copy of
None). I don't know off hand if that is feasible or not.

You reply reeks of the kind of pedantic snobbishness that makes me
sick.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Russ P.
On Jul 29, 11:16 pm, Erik Max Francis [EMAIL PROTECTED] wrote:
 Russ P. wrote:
  On Jul 29, 10:33 pm, Carl Banks [EMAIL PROTECTED] wrote:
  On Jul 30, 1:15 am, Russ P. [EMAIL PROTECTED] wrote:

  Having said that, it would sure be nice to be able to write
  if myList is not empty:
  instead of
  if len(myList) != 0:
  I can agree with this.

  But I guess that could only work if there were only one empty list
  that represents all empty lists (as there is only one actual None).
  I don't know if that makes sense or not.

 It really doesn't, since it presumably wouldn't apply to just list
 types.  There are plenty of other sequence types:  such as tuples,
 strings, or even arbitrary custom types.  Emptiness is a test for the
 value of an object, not a test for whether it is identical to another
 object, so this is a very misleading of the `is` operator, bordering on
 abuse.

 This syntax would make far less sense than the existing Boolean test.

 --
 Erik Max Francis  [EMAIL PROTECTED] http://www.alcyone.com/max/
   San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
The doors of Heaven and Hell are adjacent and identical.
 -- Nikos Kazantzakis

Now that's more reasonable. Note that I said, it would be nice to be
able to write, not this is how it should be done.

Come to think of it, shouldn't the list type have an isempty method?
Or does it?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Erik Max Francis

Russ P. wrote:


On Jul 29, 11:09 pm, Erik Max Francis [EMAIL PROTECTED] wrote:


I'm getting this sneaking suspicion that you guys are all putting us on.


As I said in an earlier post, I realize that this would only work if
there were only one copy of empty (as there is only one copy of
None). I don't know off hand if that is feasible or not.


It's only feasible if you change what `is` means for this one bizarre 
use case, which isn't a good idea.



You reply reeks of the kind of pedantic snobbishness that makes me
sick.


Well, if understanding what the `is` operator means is pedantic 
snobbishness, then hey, go right ahead.


--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  The doors of Heaven and Hell are adjacent and identical.
   -- Nikos Kazantzakis
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Erik Max Francis

Russ P. wrote:


Come to think of it, shouldn't the list type have an isempty method?
Or does it?


Yes.  It's written:

if not aList:
...

--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  The doors of Heaven and Hell are adjacent and identical.
   -- Nikos Kazantzakis
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Russ P.
On Jul 29, 11:36 pm, Erik Max Francis [EMAIL PROTECTED] wrote:
 Russ P. wrote:
  On Jul 29, 11:09 pm, Erik Max Francis [EMAIL PROTECTED] wrote:

  I'm getting this sneaking suspicion that you guys are all putting us on.

  As I said in an earlier post, I realize that this would only work if
  there were only one copy of empty (as there is only one copy of
  None). I don't know off hand if that is feasible or not.

 It's only feasible if you change what `is` means for this one bizarre
 use case, which isn't a good idea.

  You reply reeks of the kind of pedantic snobbishness that makes me
  sick.

 Well, if understanding what the `is` operator means is pedantic
 snobbishness, then hey, go right ahead.

 --
 Erik Max Francis  [EMAIL PROTECTED] http://www.alcyone.com/max/
   San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
The doors of Heaven and Hell are adjacent and identical.
 -- Nikos Kazantzakis

I fully understand what the is operator is, and I never had any
problem with it at all, thank you.

But then again, I suppose that depends on what the meaning of is
is ...
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Russ P.
On Jul 29, 11:36 pm, Erik Max Francis [EMAIL PROTECTED] wrote:
 Russ P. wrote:
  Come to think of it, shouldn't the list type have an isempty method?
  Or does it?

 Yes.  It's written:

 if not aList:
 ...

As you know, that is not quite exactly the same thing. An isempty
method would fail if aList were an integer, and such failure might be
desirable if someone mistakenly had aList pointing to an integer.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Carl Banks
On Jul 30, 2:06 am, Erik Max Francis [EMAIL PROTECTED] wrote:
 Perhaps in the particular use case you're thinking of (numeric types vs.
 container types), there aren't any good examples.  But who cares?

You don't have to.  I am trying to set the record straight on just how
much polymophism if x supports relative to explicit tests, which is
to say, not much.

BTW, I haven't changed my criteria since I asked for the challenge.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Carl Banks
On Jul 30, 1:58 am, Russ P. [EMAIL PROTECTED] wrote:
 On Jul 29, 10:33 pm, Carl Banks [EMAIL PROTECTED] wrote:

  On Jul 30, 1:15 am, Russ P. [EMAIL PROTECTED] wrote:
   Having said that, it would sure be nice to be able to write

   if myList is not empty:

   instead of

   if len(myList) != 0:

  I can agree with this.

 But I guess that could only work if there were only one empty list
 that represents all empty lists (as there is only one actual None).
 I don't know if that makes sense or not.

I mean in general.  I wouldn't spell it like that.  I would prefer if
empty(x), with an __empty__ method.  (And support __nonzero__ aka
__bool__ dropped completely.)


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Heiko Wundram
Am Mittwoch, 30. Juli 2008 08:30:48 schrieb Russ P.:
 On Jul 29, 11:09 pm, Erik Max Francis [EMAIL PROTECTED] wrote:
  I'm getting this sneaking suspicion that you guys are all putting us on.

 As I said in an earlier post, I realize that this would only work if
 there were only one copy of empty (as there is only one copy of
 None). I don't know off hand if that is feasible or not.

 You reply reeks of the kind of pedantic snobbishness that makes me
 sick.

I can understand (and pretty much sympathise) that you get this kind of reply, 
simply because the point you and Carl Banks (formulated somewhat differently) 
put up has been answered again and again (in this thread), and I can only 
repeat it once more:

__nonzero__(), i.e. the cast to boolean, is THE WAY to test whether a 
container is empty or not. Like this design decision, or don't like it, but 
the discussion is not going to go anywhere unless you concede that there is a 
(very explicit!) way to test for non-emptiness of a container already, and 
you're currently simply discussing about adding/using syntactic sugar 
(different means of expressing the test) to suit your own personal taste 
better. Anyway, check the documentation for __nonzero__(): if the object 
doesn't implement that, but implements __len__(), the interpreter replaces 
the __nonzero__() test by __len__()0, so I guess someone in the design 
department must've seen it logical for the truth value of a container to 
express the test len(x)0 at some point in time to make this interpretation 
for the truth value of a container.

There cannot be an argument about missing/misplaced functionality (that's what 
you make it sound like), if the functionality for doing what you want to do 
is there and you simply don't like the syntax, which I can somewhat relate to 
because style is a personal thing, even though I don't see either points made 
by you or Carl Banks, because implicit casting to bool is so common in pretty 
much every programming language to test for truth of an object, and IMHO 
it's completely logical to extend that idea to containers to mean 
empty/non-empty.

Eric Max Francis tried to explain why your syntactic enhancement would come 
at a much greater price than its worth, and he's absolutely right in that, as 
it's an abuse of the is operator, but again, that's a somewhat different 
point. It changes nothing about the fact that all this discussion centers 
around something that is a non-point, but simply a matter of personal taste.

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Russ P.
On Jul 30, 12:03 am, Heiko Wundram [EMAIL PROTECTED] wrote:
 Am Mittwoch, 30. Juli 2008 08:30:48 schrieb Russ P.:

  On Jul 29, 11:09 pm, Erik Max Francis [EMAIL PROTECTED] wrote:
   I'm getting this sneaking suspicion that you guys are all putting us on.

  As I said in an earlier post, I realize that this would only work if
  there were only one copy of empty (as there is only one copy of
  None). I don't know off hand if that is feasible or not.

  You reply reeks of the kind of pedantic snobbishness that makes me
  sick.

 I can understand (and pretty much sympathise) that you get this kind of reply,
 simply because the point you and Carl Banks (formulated somewhat differently)
 put up has been answered again and again (in this thread), and I can only
 repeat it once more:

 __nonzero__(), i.e. the cast to boolean, is THE WAY to test whether a
 container is empty or not. Like this design decision, or don't like it, but
 the discussion is not going to go anywhere unless you concede that there is a
 (very explicit!) way to test for non-emptiness of a container already, and
 you're currently simply discussing about adding/using syntactic sugar
 (different means of expressing the test) to suit your own personal taste
 better. Anyway, check the documentation for __nonzero__(): if the object
 doesn't implement that, but implements __len__(), the interpreter replaces
 the __nonzero__() test by __len__()0, so I guess someone in the design
 department must've seen it logical for the truth value of a container to
 express the test len(x)0 at some point in time to make this interpretation
 for the truth value of a container.

 There cannot be an argument about missing/misplaced functionality (that's what
 you make it sound like), if the functionality for doing what you want to do
 is there and you simply don't like the syntax, which I can somewhat relate to
 because style is a personal thing, even though I don't see either points made
 by you or Carl Banks, because implicit casting to bool is so common in pretty
 much every programming language to test for truth of an object, and IMHO
 it's completely logical to extend that idea to containers to mean
 empty/non-empty.

 Eric Max Francis tried to explain why your syntactic enhancement would come
 at a much greater price than its worth, and he's absolutely right in that, as
 it's an abuse of the is operator, but again, that's a somewhat different
 point. It changes nothing about the fact that all this discussion centers
 around something that is a non-point, but simply a matter of personal taste.

 --
 Heiko Wundram

Oh, Lordy. I understand perfectly well how boolean tests, __len__, and
__nonzero__ work in Python. It's very basic stuff. You can quit
patronizing me (and Carl too, I'm sure).

The point that you seem to be missing, or refuse to acknowledge for
some reason, is that  if x can be mistakenly applied to any object
when the programmer thinks that x is a list -- and the programmer will
receive no feedback on the error.

I have made errors like that, and I could have saved some time had I
used an empty method that only applies to a list or other sequence.

Is that an important issue? I don't know. I'm not claiming it is. But
you cannot just sweep it away as nothing.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Heiko Wundram
Am Mittwoch, 30. Juli 2008 09:18:48 schrieb Russ P.:
 Oh, Lordy. I understand perfectly well how boolean tests, __len__, and
 __nonzero__ work in Python. It's very basic stuff. You can quit
 patronizing me (and Carl too, I'm sure).

I'll stop repeating what the current state is (which might sound like I'm 
patronizing, but that's not the real intent actually, I'm just trying to get 
the discussion straight with what is fact, namely that there already exists 
an explicit way which doesn't seem to be recognized by some people here) if 
you agree to my point that we're not talking about a problem with Python, but 
about a personal stylistic issue with the language design. That's just what I 
said in my last mail: I can concede that you, personally, have an issue with 
the current state, but for me and seemingly also for a majority of people who 
have posted in this thread, that's a non-issue.

 The point that you seem to be missing, or refuse to acknowledge for
 some reason, is that  if x can be mistakenly applied to any object
 when the programmer thinks that x is a list -- and the programmer will
 receive no feedback on the error.

 I have made errors like that, and I could have saved some time had I
 used an empty method that only applies to a list or other sequence.

For me, I've never had this kind of problem, simply because if I test for the 
truth value of something, I'm going to do something with it later on, and as 
soon as I'm doing something with it, I'll see whether the object supports the 
interface I want it to support (and get an error there if the object doesn't 
support the basic notions of a sequence type, for example, i.e. __iter__()). 
Testing for truth is IMHO not doing something with an object, and as such I'm 
more than happy that it's foolproof. This is one thing that I personally 
find attractive about Python's way of duck-typing.

But, if you personally have been bitten by this, give an example, and I'm sure 
that we can start discussing from there. I've already given an example why 
the explicit test for length is less polymorphic than the explicit test for 
truth of a container elsewhere as a proof for the point I'm trying to make.

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Russ P.
On Jul 30, 12:49 am, Heiko Wundram [EMAIL PROTECTED] wrote:
 Am Mittwoch, 30. Juli 2008 09:18:48 schrieb Russ P.:

  Oh, Lordy. I understand perfectly well how boolean tests, __len__, and
  __nonzero__ work in Python. It's very basic stuff. You can quit
  patronizing me (and Carl too, I'm sure).

 I'll stop repeating what the current state is (which might sound like I'm
 patronizing, but that's not the real intent actually, I'm just trying to get
 the discussion straight with what is fact, namely that there already exists
 an explicit way which doesn't seem to be recognized by some people here) if
 you agree to my point that we're not talking about a problem with Python, but
 about a personal stylistic issue with the language design. That's just what I
 said in my last mail: I can concede that you, personally, have an issue with
 the current state, but for me and seemingly also for a majority of people who
 have posted in this thread, that's a non-issue.

  The point that you seem to be missing, or refuse to acknowledge for
  some reason, is that  if x can be mistakenly applied to any object
  when the programmer thinks that x is a list -- and the programmer will
  receive no feedback on the error.

  I have made errors like that, and I could have saved some time had I
  used an empty method that only applies to a list or other sequence.

 For me, I've never had this kind of problem, simply because if I test for the
 truth value of something, I'm going to do something with it later on, and as
 soon as I'm doing something with it, I'll see whether the object supports the
 interface I want it to support (and get an error there if the object doesn't
 support the basic notions of a sequence type, for example, i.e. __iter__()).
 Testing for truth is IMHO not doing something with an object, and as such I'm
 more than happy that it's foolproof. This is one thing that I personally
 find attractive about Python's way of duck-typing.

 But, if you personally have been bitten by this, give an example, and I'm sure
 that we can start discussing from there. I've already given an example why
 the explicit test for length is less polymorphic than the explicit test for
 truth of a container elsewhere as a proof for the point I'm trying to make.

 --
 Heiko Wundram

Fair enough. I have no dog in this particular fight. I just think it
wouldn't hurt to add an isempty() or isnonempty() method to the
list type, and let people use it if they wish, or continue using if
x if that's what they prefer.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Erik Max Francis

Russ P. wrote:


On Jul 29, 11:36 pm, Erik Max Francis [EMAIL PROTECTED] wrote:

Russ P. wrote:

Come to think of it, shouldn't the list type have an isempty method?
Or does it?

Yes.  It's written:

if not aList:
...


As you know, that is not quite exactly the same thing. An isempty
method would fail if aList were an integer, and such failure might be
desirable if someone mistakenly had aList pointing to an integer.


If you're that concerned about what the type is, then you can do 
explicit typechecks.  Those are discouraged precisely because of 
Python's dynamism.  But knock yourself out.


--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  The actor is not quite a human being -- but then, who is?
   -- George Sanders
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Erik Max Francis

Carl Banks wrote:


I mean in general.  I wouldn't spell it like that.  I would prefer if
empty(x), with an __empty__ method.  (And support __nonzero__ aka
__bool__ dropped completely.)


So your argument is purely about style, then.  You just wish it were 
written differently.


--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  The actor is not quite a human being -- but then, who is?
   -- George Sanders
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Erik Max Francis

Russ P. wrote:


Oh, Lordy. I understand perfectly well how boolean tests, __len__, and
__nonzero__ work in Python. It's very basic stuff. You can quit
patronizing me (and Carl too, I'm sure).


You suggested a syntax for testing non-emptiness (`x is not empty`) 
which indicated a profound misunderstanding of what the `is` operator does.


You then acknowledged that there might be a problem because of the 
implication if the `is` operator and weren't sure whether it would work 
or not:


| But I guess that could only work if there were only one empty list
| that represents all empty lists (as there is only one actual None).
| I don't know if that makes sense or not.

This ends with you still sounding confused about what the operator does, 
because that can't make sense if you take into account the meaning of 
the `is` operator (surely not all empty lists are the same object) and 
polymorphism (not all empty containers are empty lists).


Hey, everybody goofs.  But pointing figures here doesn't help, since 
it's not unreasonable to assume that someone who says something clearly 
misunderstanding a feature of the language, and followups to responses 
_continuing to be confused about it_, is, in fact, confused.  The only 
reason anyone thought you were confused was by your bizarre suggestion 
about the `empty` syntax and then your confused responses afterwards.


Maybe chalk it up to experience and move on?


The point that you seem to be missing, or refuse to acknowledge for
some reason, is that  if x can be mistakenly applied to any object
when the programmer thinks that x is a list -- and the programmer will
receive no feedback on the error.

I have made errors like that, and I could have saved some time had I
used an empty method that only applies to a list or other sequence.


Well, that's what you get when you use a dynamic language.  There are 
times when `x + y` doesn't mean numeric addition, or in fact anything 
like it.  Or `x % y` where it _really_ doesn't mean anything like the 
modulus operator.  In dynamic languages, the effect of operations depend 
on their types.  There's really no way around that, and Boolean testing 
if an object as in `if x: ...` is no different.  It means different 
things depending on what `x` is.


--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  The actor is not quite a human being -- but then, who is?
   -- George Sanders
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Ethan Furman

Russ P. wrote:

Oh, Lordy. I understand perfectly well how boolean tests, __len__, and
__nonzero__ work in Python. It's very basic stuff. You can quit
patronizing me (and Carl too, I'm sure).

The point that you seem to be missing, or refuse to acknowledge for
some reason, is that  if x can be mistakenly applied to any object
when the programmer thinks that x is a list -- and the programmer will
receive no feedback on the error.


You know... or maybe you don't, since you did just say what you just 
said... that is such a ridiculous point it only barely qualifies as 
deserving comment.  Rather than be really rude, I'll just say:  test 
it's type() if the function is that specific, or your code that brittle. 
 Python is not there to catch your logic mistakes, that's up to you.



I have made errors like that, and I could have saved some time had I
used an empty method that only applies to a list or other sequence.

Is that an important issue? I don't know. I'm not claiming it is. But
you cannot just sweep it away as nothing.


I don't sweep it away as nothing -- I sweep it away as stupid.  The 
programmer is responsible for his (or her) program.  An analogy would be 
a driver and a car -- if the driver cannot handle the power and speed of 
a fancy car (python :), then the driver should get a different car 
better matched to his abilities.  It's not up to the car to say oh, the 
speed limit is 50 here, I better apply the brakes for the driver.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Maric Michaud
Le Tuesday 29 July 2008 23:48:31 [EMAIL PROTECTED], vous avez écrit :
 Here's a function, print_members.  It's just something that takes some
 iterable and prints its members in XML.  It's special-cased so that an
 empty iterable gets an empty tag.  (This is a bit of a trivial
 example, I admit; the point is that the empty iterable is a special
 case.)

 def print_members(iterable):
     if not iterable:
         print 'members /'
         return
     print 'members'
     for item in iterable:
         print 'item%s/item' % item
     print '/members'


... 
 So print_members can work on iterables that have no len(), and handle
 the special case of an empty iterable, as long as __nonzero__ is
 implemented.


But iterables can have no notion of emptiness too :

[25]: print_members((e for e in range(0)))
members
/members

Your function is just wrong assuming that, it should be written :

[31]: def print_members(iterable):
print 'members',
empty = True
for item in iterable:
if empty :
empty = False
print ''
print 'item%s/item' % item
print empty and '/' or '/members'
   :
   :

[40]: print_members((e for e in range(0)))
members /

[41]: print_members((e for e in range(1)))
members 
item0/item
/members



 Counterexample:

 While if x works well in some circumstances, I don't like using it
 for purely numeric types.  For instance, I have a mutable Signal class
 for doing some basic DSP.  Among other things, I can apply a DC offset
 to the signal (it just adds the offset to all the samples).  I have a
 special case for an offset of 0 so I don't have to loop through all
 the samples (I also have a two-pass remove_offset method that
 subtracts the average; if it's already properly centred, I can skip a
 step).

 class Signal:
     [...]
     def dc_offset(self, amount):
         if amount == 0:
             return
         self.samples = [sample + amount for sample in self.samples]

This function is also wrong assuming that because amount compare to zero, it 
can be added to sample.

If you want to make type checking just check the type or convert your 
parameter to an int, but the test == 0 is of no help here.

The only valuable point I see for this idiom is to make more explicit I am 
testing a numerical value.
But your example is a good objection to this, with well chosen name, ie. 
amount, it's quite clear if not amount : is testing the zero value of a 
numerical value.

-- 
_

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread giltay
On Jul 30, 5:09 am, Maric Michaud [EMAIL PROTECTED] wrote:
 Le Tuesday 29 July 2008 23:48:31 [EMAIL PROTECTED], vous avez écrit :
  def print_members(iterable):
      if not iterable:
          print 'members /'
          return
      print 'members'
      for item in iterable:
          print 'item%s/item' % item
      print '/members'

 But iterables can have no notion of emptiness too :

 [25]: print_members((e for e in range(0)))

 members
 /members

Ack!  Maybe I meant container rather than iterable.  Or maybe I'd
be wrong on that count, too.  Other people have come up with better
examples, so I won't try to fix my hasty code (although I'll keep that
in mind if I have to write a custom XML writer).

  class Signal:
      [...]
      def dc_offset(self, amount):
          if amount == 0:
              return
          self.samples = [sample + amount for sample in self.samples]

 This function is also wrong assuming that because amount compare to zero, it
 can be added to sample.

Not quite.  I'm assuming that if amount equals 0, then amount is some
scalar.  In fact, only if that comparison fails will I get my
exception: since [] != 0, it will then try to add sample + [], which
will raise TypeError.

 If you want to make type checking just check the type or convert your
 parameter to an int, but the test == 0 is of no help here.

I'm not going for type checking here because I want Signal to support
int and float samples (and numpy.int16, c.).

 The only valuable point I see for this idiom is to make more explicit I am
 testing a numerical value.

That's one of the reasons I wrote it that way.  Signal has other
methods that take lists (like mix and envelope), which I could get
confused with the ones that take scalars (offset and change volume).

 Cheers,
Geoff G-T
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Hyuga
On Jul 30, 3:53 am, Russ P. [EMAIL PROTECTED] wrote:
 Fair enough. I have no dog in this particular fight. I just think it
 wouldn't hurt to add an isempty() or isnonempty() method to the
 list type, and let people use it if they wish, or continue using if
 x if that's what they prefer.

Go right on ahead.  You could implement it like this:

class superenhancedlist(list):
def isempty(self):
return not self

 a = superenhancedlist()
 a.isempty()
True
 a.append(1)
 a.isempty()
False

Amazingly useful!  Go ahead and use that in all your code.  Anyone
else who comes along and looks at it or tries to maintain it will
really love you for it.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Maric Michaud
Le Wednesday 30 July 2008 15:31:28 [EMAIL PROTECTED], vous avez écrit :
   class Signal:
       [...]
       def dc_offset(self, amount):
           if amount == 0:
               return
           self.samples = [sample + amount for sample in self.samples]
 
  This function is also wrong assuming that because amount compare to zero,
  it can be added to sample.

 Not quite.  I'm assuming that if amount equals 0, then amount is some
 scalar.  In fact, only if that comparison fails will I get my
 exception: since [] != 0, it will then try to add sample + [], which
 will raise TypeError.

  If you want to make type checking just check the type or convert your
  parameter to an int, but the test == 0 is of no help here.

 I'm not going for type checking here because I want Signal to support
 int and float samples (and numpy.int16, c.).

Ok, but the fact that amount == 0 passes, doesn't ensure you didn't a 
programming error, this add just some relative robustness (protect you from 
passing an empty list). And a reader would probably not see your intention 
here (he already expect a scalar due to the name of the variable).

This is exactly the problem ABC is intended to solve.

Without ABC, to explicitly ensure amount is a scalar, just doing a int(amount) 
or int(abs(amount)) if you want to deal with complex numbers too, at the 
begining of the function is a common idiom.

-- 
_

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Terry Reedy



Carl Banks wrote:


That's not what I was asking for.  I was asking for a use case for if
x that can't be replaced by a simple explicit test.  Your example
didn't satisfy that.


But I believe my example of an iterator with __bool__ but not with 
__len__ does.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Matthew Fitzgibbons

Carl Banks wrote:

On Jul 30, 1:58 am, Russ P. [EMAIL PROTECTED] wrote:

On Jul 29, 10:33 pm, Carl Banks [EMAIL PROTECTED] wrote:


On Jul 30, 1:15 am, Russ P. [EMAIL PROTECTED] wrote:

Having said that, it would sure be nice to be able to write
if myList is not empty:
instead of
if len(myList) != 0:

I can agree with this.

But I guess that could only work if there were only one empty list
that represents all empty lists (as there is only one actual None).
I don't know if that makes sense or not.


I mean in general.  I wouldn't spell it like that.  I would prefer if
empty(x), with an __empty__ method.  (And support __nonzero__ aka
__bool__ dropped completely.)


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



__nonzero__ is not only meaningful for sequence types.

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Matthew Fitzgibbons

Russ P. wrote:

On Jul 30, 12:03 am, Heiko Wundram [EMAIL PROTECTED] wrote:

Am Mittwoch, 30. Juli 2008 08:30:48 schrieb Russ P.:


On Jul 29, 11:09 pm, Erik Max Francis [EMAIL PROTECTED] wrote:

I'm getting this sneaking suspicion that you guys are all putting us on.

As I said in an earlier post, I realize that this would only work if
there were only one copy of empty (as there is only one copy of
None). I don't know off hand if that is feasible or not.
You reply reeks of the kind of pedantic snobbishness that makes me
sick.

I can understand (and pretty much sympathise) that you get this kind of reply,
simply because the point you and Carl Banks (formulated somewhat differently)
put up has been answered again and again (in this thread), and I can only
repeat it once more:

__nonzero__(), i.e. the cast to boolean, is THE WAY to test whether a
container is empty or not. Like this design decision, or don't like it, but
the discussion is not going to go anywhere unless you concede that there is a
(very explicit!) way to test for non-emptiness of a container already, and
you're currently simply discussing about adding/using syntactic sugar
(different means of expressing the test) to suit your own personal taste
better. Anyway, check the documentation for __nonzero__(): if the object
doesn't implement that, but implements __len__(), the interpreter replaces
the __nonzero__() test by __len__()0, so I guess someone in the design
department must've seen it logical for the truth value of a container to
express the test len(x)0 at some point in time to make this interpretation
for the truth value of a container.

There cannot be an argument about missing/misplaced functionality (that's what
you make it sound like), if the functionality for doing what you want to do
is there and you simply don't like the syntax, which I can somewhat relate to
because style is a personal thing, even though I don't see either points made
by you or Carl Banks, because implicit casting to bool is so common in pretty
much every programming language to test for truth of an object, and IMHO
it's completely logical to extend that idea to containers to mean
empty/non-empty.

Eric Max Francis tried to explain why your syntactic enhancement would come
at a much greater price than its worth, and he's absolutely right in that, as
it's an abuse of the is operator, but again, that's a somewhat different
point. It changes nothing about the fact that all this discussion centers
around something that is a non-point, but simply a matter of personal taste.

--
Heiko Wundram


Oh, Lordy. I understand perfectly well how boolean tests, __len__, and
__nonzero__ work in Python. It's very basic stuff. You can quit
patronizing me (and Carl too, I'm sure).

The point that you seem to be missing, or refuse to acknowledge for
some reason, is that  if x can be mistakenly applied to any object
when the programmer thinks that x is a list -- and the programmer will
receive no feedback on the error.

I have made errors like that, and I could have saved some time had I
used an empty method that only applies to a list or other sequence.

Is that an important issue? I don't know. I'm not claiming it is. But
you cannot just sweep it away as nothing.
--
http://mail.python.org/mailman/listinfo/python-list



See, I can agree with this. If you're expecting a list (and only a list) 
then your point makes sense. 'if x' can get you into trouble if you 
_don't_ want its polymorphism.


Although, if my function is expecting a list, my preference is to do:

if not isinstance(x, list):
raise SomeMeaningfulException()
# do stuff with the list

I put my type checking at the top of the function, so readers can 
reference it easily.


However, Carl's point is that 'if x' is never preferable to the more 
verbose and slower simple test. I do not agree with this.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Matthew Fitzgibbons

Carl Banks wrote:

On Jul 29, 6:42 pm, Matthew Fitzgibbons [EMAIL PROTECTED] wrote:

Carl Banks wrote:

Much like in Steven D'Aprano's example, still the only actual code
snippet I've seen, it seems that this can easily be done with a simple
explicit test by having all no-advance filters return None and testing
with if x is not None.  So it doesn't pass my criterion of being not
replaceable with simple explicit test.
Maybe that's not workable for some reason.  Perhaps if you'd post a
code example that shows this, rather than just talking about it, you
might be more persuasive.
Carl Banks
--
http://mail.python.org/mailman/listinfo/python-list

The no-advance filters have to return the object because I don't just
forget about it; I evaluate whether I pass it to the next filter or drop
it in a completely different queue for use in the next stage of the
operation. True means 'I'm ready to move on to the next stage,' False
means 'Do the filter thing some more.'


I think I see what you're saying, and yeah I guess that could really
take advantage of polymorphism between very different types.


Furthermore, the argument that I should just change my API to make a
'simple test' work is not very convincing.


I wasn't suggesting you change it: I was trying to ascertain whether
it would have suffered much if you had written it with explicit tests
in the first place, or if Python didn't even have magical booleans.


Yes it would have suffered. I chose the implementation I did because it 
made the most sense to me and was the most flexible (a key requirement). 
Instead of cobbling together my own way, I used the way that Python gave me.


Python doesn't have magic booleans. They are instead a very well-defined 
language mechanism that isn't perfect for every circumstance, but is 
pretty good for the most part. I wanted to do meaningful boolean tests 
on various objects, so I used the mechanism that my language gave me.





The natural, obvious way for
a filter to work is to pass through the data it operates on; why on
Earth would it return None? I want to DO something with the data. In
this case, make a decision about where to pass the data next.


If you don't mind me asking: what do you do actually DO with a zero or
empty list?


Depends on exactly what the next stage is. Typically, zeros and empty 
lists are not meaningful for the next stage, so they get dropped then if 
they make it through. I don't want to restrict what gets passed through, 
though, because I could end up with several meaningful data types, 
making a simple test again impossible. So I pass everything through and 
let the next stage decide.





In Java,
to accomplish this I would have to do lots of introspection and value
checking (adding more any time I came up with a new kind of input), or
make a new kind of interface that gives me a method so I can do a
'simple test' (including wrappers for ints and arrays and anything else
I decide to pass in down the road). But Python supports duck typing and
gives me a handy __nonzero__ method; I can rebind __nonzero__ in my
filters for my own classes, and ints and lists are handled how I want
them to be by default. So why jump through hoops instead of just using
'if x'?


Ah, so it's just happens to work.  Still, just happening to work
works. (shrug)


Nonono. The point you seem to be missing is that 'if x' is very well 
defined. There is nothing magic or arbitrary about what it does. It 
works here and elsewhere because Python (a) chooses good default 
behavior (its treatment of lists and ints, etc) and (b) gives you a way, 
__nonzero__, to change the behavior to suit your needs.





I don't have any postable code (it's in a half way state and I haven't
touched it for a while), but I'll see if I can't find the time to bang
something up to give you the gist.


I wouldn't bother at this point.  I was looking to see if someone
could come up with something to disprove my belief on the polymorphic
uselessness of if x relative to explicit tests, and if (as I
anticipated) they did not, I could claim that if x is really just a
glorified keystroke saver.  But I now realize that the failure of this
bunch doesn't prove anything.  I don't think most people even realize
why answering the question I asked would demonstrate the usefulness of
if x.


Of course you don't _need_ to have 'if x'; after all, sarcasmREAL 
programmers code in machine language/sarcasm. The whole point of a 
high-level language is to make life easier. Python is very dynamic and 
allows duck typing so that you can use these tools to do clever things 
that would otherwise be very difficult. It even gives you a handy 
polymorphic mechanism to do boolean tests, which my example illustrates.


You asked for a use case for a polymorphic 'if x' that can't be easily 
replaced by a simple test. I gave one. Then you asked for a code sample, 
but now have dismissed my sample as not compelling without having seen 
it. But here it is anyway (attached). 

Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Ethan Furman

Carl Banks wrote:

On Jul 29, 6:42 pm, Matthew Fitzgibbons [EMAIL PROTECTED] wrote:

I don't have any postable code (it's in a half way state and I haven't
touched it for a while), but I'll see if I can't find the time to bang
something up to give you the gist.


I wouldn't bother at this point.  I was looking to see if someone
could come up with something to disprove my belief on the polymorphic
uselessness of if x relative to explicit tests, and if (as I
anticipated) they did not, I could claim that if x is really just a
glorified keystroke saver.  But I now realize that the failure of this
bunch doesn't prove anything.  I don't think most people even realize
why answering the question I asked would demonstrate the usefulness of
if x.

Your example isn't exactly the smoking gun I was looking for, but I
guess we'll have to admit that at least one usage will suffer for not
having it.

Carl Banks


Even for those that did realize, and in fact hoped that that is what you 
were attempting to accomplish, it was still quite frustrating to see you 
ignoring all the non-code, yet perfectly valid examples of why if x 
was not only valid, but the most pythonic[1] way to get the task done. 
I think it would have been a better discussion if you had responded with 
reasons why, and not just parroted the show me the code! line over and 
over and over and ...  It seemed as if you thought you were the 
professor, impatiently trying to teach a class full of idiots by playing 
the devil's advocate.  I was sure hoping someone would get the actual 
code example and post it, partly because I enjoy learning, but mostly 
because it would (hopefully) shut you up and move the conversation 
along.  In fact, somebody did post some code about a custom matrix 
class, where __len__ was useless, and still you kept on with...  pah. 
It's late, so before I say something stupid I'll finish this.  My last 
thought on the matter -- up until this thread I had looked forward to 
your posts, Carl.  I think you did more damage than good to yourself 
with this stunt.

~Ethan~

[1] by pythonic I mean using the features of the language that make 
sense.  In this case, the __nonzero__ function to have the object in 
question tell us whether or not it's empty.  This seems so basic (the 
__nonzero__ function, that is, and its purpose) -- do you really need 
code to prove it to yourself?



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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Matthew Woodcraft
Terry Reedy  [EMAIL PROTECTED] wrote:
Carl Banks wrote:

 That's not what I was asking for.  I was asking for a use case for if
 x that can't be replaced by a simple explicit test.  Your example
 didn't satisfy that.

 But I believe my example of an iterator with __bool__ but not with 
 __len__ does.

On the other hand, iterators provide a clear example of problems with if x:
__nonzero__ for iterators (in general) returns True even if they are 'empty'.

For example, this function (which attempts to avoid making an expensive
call when not necessary) is buggy, but easy to write if you've been
taught that if x will work with any kind of object.

def frob(widgets, power):
if widgets:
frobber = Frobber(power) # expensive call
for widget in widgets:
frobber.frob(widget)

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Russ P.
On Jul 30, 1:07 am, Erik Max Francis [EMAIL PROTECTED] wrote:
 Russ P. wrote:
  Oh, Lordy. I understand perfectly well how boolean tests, __len__, and
  __nonzero__ work in Python. It's very basic stuff. You can quit
  patronizing me (and Carl too, I'm sure).

 You suggested a syntax for testing non-emptiness (`x is not empty`)
 which indicated a profound misunderstanding of what the `is` operator does.

 You then acknowledged that there might be a problem because of the
 implication if the `is` operator and weren't sure whether it would work
 or not:

Oh, my. I wrote something like, It would sure be nice to be able to
write

if x is not empty:

because it reads like natural language. Immediately after I posted it,
I thought, oh, I'll bet some idiot takes that as a serious proposal.
Sure enough, some idiot did just that almost immediately. And he is
still patronizing me for it.

Hey, dude, if you think I ever had any doubt about what is means in
Python, you are simply wrong. Completely wrong. Can you get that
through your thick skull?

One of the problems with this site is that you have pedants who like
to show off their knowledge of the Python language. I suspect that
many of these people know little more than the rules of programming in
Python. They are like someone who thinks he is a writer because he
knows how to use Microsoft Word, or someone who thinks he is a chess
expert because he knows the rules for moving the pieces.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Carl Banks
On Jul 30, 11:07 am, Terry Reedy [EMAIL PROTECTED] wrote:
 Carl Banks wrote:
  That's not what I was asking for.  I was asking for a use case for if
  x that can't be replaced by a simple explicit test.  Your example
  didn't satisfy that.

 But I believe my example of an iterator with __bool__ but not with
 __len__ does.

And I believe I followed up to your post saying as much. :)


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Carl Banks
On Jul 30, 3:56 am, Erik Max Francis [EMAIL PROTECTED] wrote:
 Carl Banks wrote:
  I mean in general.  I wouldn't spell it like that.  I would prefer if
  empty(x), with an __empty__ method.  (And support __nonzero__ aka
  __bool__ dropped completely.)

 So your argument is purely about style, then.  You just wish it were
 written differently.

No, you misunderstand and/or misstate my position again.  I realize I
wasn't as clear as I could have been.  First of all it's not my
argument: this is a tangent.

There would be a built-in empty, which invokes __empty__, in the same
way len invokes __len__.  It would only be defined for container
types.  (Iterators could choose whether to define it and it would mean
that the iterator is guaranteed stop on the next iteration.  The
iterator is free to read and store the item.  If the iterator doesn't
know whether it will stop, it must not define __empty__ or raise an
exception in it.)  It would become the One Obvious Way to test for
emptiness.  __nonzero__ would disappear and not be replaced with
anything, and objects would not have implicit boolean conversion.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Carl Banks
On Jul 30, 4:49 am, Ethan Furman [EMAIL PROTECTED] wrote:
 Carl Banks wrote:
  On Jul 29, 6:42 pm, Matthew Fitzgibbons [EMAIL PROTECTED] wrote:
  I don't have any postable code (it's in a half way state and I haven't
  touched it for a while), but I'll see if I can't find the time to bang
  something up to give you the gist.

  I wouldn't bother at this point.  I was looking to see if someone
  could come up with something to disprove my belief on the polymorphic
  uselessness of if x relative to explicit tests, and if (as I
  anticipated) they did not, I could claim that if x is really just a
  glorified keystroke saver.  But I now realize that the failure of this
  bunch doesn't prove anything.  I don't think most people even realize
  why answering the question I asked would demonstrate the usefulness of
  if x.

  Your example isn't exactly the smoking gun I was looking for, but I
  guess we'll have to admit that at least one usage will suffer for not
  having it.

  Carl Banks

 Even for those that did realize, and in fact hoped that that is what you
 were attempting to accomplish,

I was not attempting to accomplish what you think I was.

I was looking for it, but I didn't want to see it.  I didn't expect to
see it.  I wanted to show that if x doesn't have the polymorphic
advantage people mindlessly claim it does by posing the challenge and
having people fail to meet it, and for the most part the examples that
met the challenge were for minor usages.  Ok, someone wrote a filter
that truly benefits from polymorphism of if x against very different
types, but really, these use cases aren't all that common.

It's not like it's an everyday thing for you to write if x instead
of if x!=0, and that it actually saves you from having to rewrite
the condition because later you decided to use a list.

So I stand by the point I was trying to make: for your average day-to-
day programming, the main benefit of if x is to save keystrokes.  It
doesn't help your code become more polymophic in practice.  A little
more polymorphic, yes.  A lot, no.

 it was still quite frustrating to see you
 ignoring all the non-code, yet perfectly valid examples of why if x
 was not only valid, but the most pythonic[1] way to get the task done.

Pfft.  The usage of if x might be Pythonic, but I think the best way
is the way Java does it.

 I think it would have been a better discussion if you had responded with
 reasons why, and not just parroted the show me the code! line over and
 over and over and ... It seemed as if you thought you were the
 professor, impatiently trying to teach a class full of idiots by playing
 the devil's advocate.

I wasn't playing Devil's advocate, I was playing the Devil.  That's
why I did that.  Sorry if it irritated people but I wasn't about to
those things distract me.

 I was sure hoping someone would get the actual
 code example and post it, partly because I enjoy learning, but mostly
 because it would (hopefully) shut you up and move the conversation
 along.  In fact, somebody did post some code about a custom matrix
 class, where __len__ was useless, and still you kept on with...  pah.

I admit it!  I downplay even successful examples because I just don't
like implicit booleans.  What can I say, I'm an optimist.

I didn't see any custom matrix class, BTW.  The only code I saw was
Steven D'Aprano filter which he still apparently expects me to take
his word for it that the alternative I proposed won't work, and Terry
Reedy's empty-enabled iterator.  Oh, also Heiko Wundram's integer set.

 It's late, so before I say something stupid I'll finish this.  My last
 thought on the matter -- up until this thread I had looked forward to
 your posts, Carl.  I think you did more damage than good to yourself
 with this stunt.

Sorry, but I must go on a crusade every once in awhile, whatever
damage it may cause my esteem.  It's in my nature.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Erik Max Francis

Russ P. wrote:


On Jul 30, 1:07 am, Erik Max Francis [EMAIL PROTECTED] wrote:

Russ P. wrote:

Oh, Lordy. I understand perfectly well how boolean tests, __len__, and
__nonzero__ work in Python. It's very basic stuff. You can quit
patronizing me (and Carl too, I'm sure).

You suggested a syntax for testing non-emptiness (`x is not empty`)
which indicated a profound misunderstanding of what the `is` operator does.

You then acknowledged that there might be a problem because of the
implication if the `is` operator and weren't sure whether it would work
or not:


Oh, my. I wrote something like, It would sure be nice to be able to
write

if x is not empty:

because it reads like natural language. Immediately after I posted it,
I thought, oh, I'll bet some idiot takes that as a serious proposal.
Sure enough, some idiot did just that almost immediately.


Yes, all people are idiots for reading what you wrote, reading your 
later realization that it was wrong, and taking both at face value. 
I'll be sure never to make that mistake again!



And he is
still patronizing me for it.


No, I'm not patronizing you for your initial misstatement.  I'm mocking 
you for your pathetic and transparent attempt to backpedal away from it. 
 Just give it up, already.


--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  Drifting from woman-who-tries misconstrued / Shifting to woman-wise
   -- Lamya
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread castironpi
On Jul 30, 1:50 am, Carl Banks [EMAIL PROTECTED] wrote:
 On Jul 30, 1:58 am, Russ P. [EMAIL PROTECTED] wrote:



  On Jul 29, 10:33 pm, Carl Banks [EMAIL PROTECTED] wrote:

   On Jul 30, 1:15 am, Russ P. [EMAIL PROTECTED] wrote:
Having said that, it would sure be nice to be able to write

if myList is not empty:

instead of

if len(myList) != 0:

   I can agree with this.

  But I guess that could only work if there were only one empty list
  that represents all empty lists (as there is only one actual None).
  I don't know if that makes sense or not.

 I mean in general.  I wouldn't spell it like that.  I would prefer if
 empty(x), with an __empty__ method.  (And support __nonzero__ aka
 __bool__ dropped completely.)

 Carl Banks

An __empty__ method could return True for my social life, ha ha.  Does
__nonzero__ just mean __nonempty__?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Russ P.
On Jul 30, 7:05 pm, Erik Max Francis [EMAIL PROTECTED] wrote:
 Russ P. wrote:
  On Jul 30, 1:07 am, Erik Max Francis [EMAIL PROTECTED] wrote:
  Russ P. wrote:
  Oh, Lordy. I understand perfectly well how boolean tests, __len__, and
  __nonzero__ work in Python. It's very basic stuff. You can quit
  patronizing me (and Carl too, I'm sure).
  You suggested a syntax for testing non-emptiness (`x is not empty`)
  which indicated a profound misunderstanding of what the `is` operator does.

  You then acknowledged that there might be a problem because of the
  implication if the `is` operator and weren't sure whether it would work
  or not:

  Oh, my. I wrote something like, It would sure be nice to be able to
  write

  if x is not empty:

  because it reads like natural language. Immediately after I posted it,
  I thought, oh, I'll bet some idiot takes that as a serious proposal.
  Sure enough, some idiot did just that almost immediately.

 Yes, all people are idiots for reading what you wrote, reading your
 later realization that it was wrong, and taking both at face value.
 I'll be sure never to make that mistake again!

  And he is
  still patronizing me for it.

 No, I'm not patronizing you for your initial misstatement.  I'm mocking
 you for your pathetic and transparent attempt to backpedal away from it.
   Just give it up, already.

 --
 Erik Max Francis  [EMAIL PROTECTED] http://www.alcyone.com/max/
   San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
Drifting from woman-who-tries misconstrued / Shifting to woman-wise
 -- Lamya

The reason I wrote that it would be nice to be able to write

if x is not empty:

is that it reads naturally. It was not an actual proposal, and the
fact that you took it as such was *your* mistake. I can understand
your misunderstanding one time, but you have now repeated it three
times, despite my (unnecessary) explanations. One more time, and you
graduate from idiot to moron.

Having said that, the syntax I wrote *could* conceivably work IF all
empty lists pointed to one empty list, just as all values set to None
actually point to the same None. That is possible, but probably not a
good idea.

Now read carefully: I DID NOT CLAIM THAT THIS IS THE WAY TO DO IT! Let
me repeat that for you: I DID NOT CLAIM THAT THIS IS THE WAY TO DO IT!
Did you get that, idiot?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Steven D'Aprano
On Wed, 30 Jul 2008 09:23:05 -0600, Matthew Fitzgibbons wrote:

 If you're expecting a list (and only a list)
 then your point makes sense. 'if x' can get you into trouble if you
 _don't_ want its polymorphism.

if x is hardly unique in that way. If you're expecting a list, and only 
a list, len(x) != 0 will get you in trouble if somebody passes a string 
or a dictionary. I don't see any reason why we should single out if x 
as dangerous in the face of invalid types. With the exception of the is 
and is not operators, nothing in Python is guaranteed to work with any 
imaginable object. Even print can fail, if the object's __str__ method 
raises an exception.

 
 Although, if my function is expecting a list, my preference is to do:
 
 if not isinstance(x, list):
  raise SomeMeaningfulException()
 # do stuff with the list
 
 I put my type checking at the top of the function, so readers can
 reference it easily.

And thus you break duck-typing and upset anybody who wants to pass a 
sequence that doesn't inherit directly from list.

There are other (and arguably better, although more labour-intensive) 
techniques for defensive programming that don't break duck-typing. You 
can google for Look Before You Leap and Easier To Ask Forgiveness Than 
Permission for more information. Alex Martelli has a fine recipe in the 
Python Cookbook -- search for the recipe Checking if an object has the 
necessary attributes.

But in a nutshell, here's a toy example:

def spam(seq):
try:
seq.append
seq.extend
seq[0] = seq[0]
except Exception:
raise TypeError(argument isn't sufficiently sequence-like)
# No exceptions expected from here on
seq.append(seq[0])
seq.extend([1,2,3])
seq[0] = spam




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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Steven D'Aprano
On Wed, 30 Jul 2008 20:55:03 +0100, Matthew Woodcraft wrote:

 On the other hand, iterators provide a clear example of problems with
 if x: __nonzero__ for iterators (in general) returns True even if they
 are 'empty'.

How do you propose telling whether an iterator is empty?

That's a generic problem with any sort of lazy function. You don't know 
if it has finished unless you try grabbing data from it.



 For example, this function (which attempts to avoid making an expensive
 call when not necessary) is buggy, but easy to write if you've been
 taught that if x will work with any kind of object.
 
 def frob(widgets, power):
 if widgets:
 frobber = Frobber(power) # expensive call
 for widget in widgets:
 frobber.frob(widget)


AFAIK there's no great solution to this problem. It's inherent in the way 
lazy functions work. Certainly you can't replace the call to if widgets 
with if len(widgets), because iterators don't have a length.

However, there is a good (but not great) solution:

def frob(widgets, power):
widgets = iter(widgets)  # in case widgets is a sequence
try:
first = widgets.next()
except StopIteration:
# empty iterator, nothing to do
return None
frobber = Frobber(power) # expensive call
frobber.frob(widget)
for widget in widgets:
frobber.frob(widget)


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Erik Max Francis

Russ P. wrote:


The reason I wrote that it would be nice to be able to write

if x is not empty:

is that it reads naturally. It was not an actual proposal, and the
fact that you took it as such was *your* mistake.

...

Now read carefully: I DID NOT CLAIM THAT THIS IS THE WAY TO DO IT! Let
me repeat that for you: I DID NOT CLAIM THAT THIS IS THE WAY TO DO IT!
Did you get that, idiot?


So people who can read words but not minds are idiots.  Go get 'em, tiger!

--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  If you turned right / You turned left / Or if you just walked out
   ahead -- Anggun
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Ethan Furman

Carl Banks wrote:

On Jul 30, 4:49 am, Ethan Furman [EMAIL PROTECTED] wrote:

Even for those that did realize, and in fact hoped that that is what you
were attempting to accomplish,


I was not attempting to accomplish what you think I was.

I was looking for it, but I didn't want to see it.  I didn't expect to
see it.  I wanted to show that if x doesn't have the polymorphic
advantage people mindlessly claim it does by posing the challenge and
having people fail to meet it, and for the most part the examples that
met the challenge were for minor usages.  Ok, someone wrote a filter
that truly benefits from polymorphism of if x against very different
types, but really, these use cases aren't all that common.

It's not like it's an everyday thing for you to write if x instead
of if x!=0, and that it actually saves you from having to rewrite
the condition because later you decided to use a list.


Actually, I use this construction a lot.  But everybody has their own 
style, and I'm certainly not going to tell you yours is wrong.  One of 
the fellows that works for me *loves* the (result if false, result if 
true)[condition] style of immediate if's -- it's one of the first things 
he learned about when studying Python, and he grins every time he talks 
about it; *I* know it's not the best way to do it, and that it has it's 
own set of gotchas -- so I made sure he was also aware of them, and uses 
them where and when they won't blow up in our faces.



So I stand by the point I was trying to make: for your average day-to-
day programming, the main benefit of if x is to save keystrokes.  It
doesn't help your code become more polymophic in practice.  A little
more polymorphic, yes.  A lot, no.


[snippitysnipsnip]


Carl Banks


Hmmm... well, I see your point.  Unfortunately, even though it feels 
incorrect to me, I do not (yet) have the breadth and depth of Python 
experience to come up with an example that would display such exquisite 
polymorphism.  It also seems to me that such an example would be 
non-trivial in nature.  Perhaps starting a new thread with this 
challenge, and adequate time (couple weeks at least, I would think) 
would net you the smoking gun you were after.


At any rate, from my point of view, I like it.  I like the visual 
clarity and simplistic nature of if x -- it tells me if x is 
something, and I trust myself enough to know what I can do with the 
something that is x.  I also expect anyone else passing me a something 
to know it has the appropriate interface to work with my code.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Russ P.
On Jul 30, 8:03 pm, Erik Max Francis [EMAIL PROTECTED] wrote:
 Russ P. wrote:
  The reason I wrote that it would be nice to be able to write

  if x is not empty:

  is that it reads naturally. It was not an actual proposal, and the
  fact that you took it as such was *your* mistake.
 ...
  Now read carefully: I DID NOT CLAIM THAT THIS IS THE WAY TO DO IT! Let
  me repeat that for you: I DID NOT CLAIM THAT THIS IS THE WAY TO DO IT!
  Did you get that, idiot?

 So people who can read words but not minds are idiots.  Go get 'em, tiger!

I don't know if you can read minds, but you seem to have a lot of
trouble reading words.

Can you read it would be nice to be able to write ...? Can you
understand what it means? Can you understand that it does *not* mean,
one *should* be able to write ...?

The really significant question here is why I waste my valuable time
with pedants like you.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Steven D'Aprano
On Thu, 31 Jul 2008 02:41:08 +, Steven D'Aprano wrote:

 On Wed, 30 Jul 2008 09:23:05 -0600, Matthew Fitzgibbons wrote:
...
 Although, if my function is expecting a list, my preference is to do:
 
 if not isinstance(x, list):
  raise SomeMeaningfulException()
 # do stuff with the list
 
 I put my type checking at the top of the function, so readers can
 reference it easily.
 
 And thus you break duck-typing and upset anybody who wants to pass a
 sequence that doesn't inherit directly from list.

Correction: delete directly from the above.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Ethan Furman

Russ P. wrote:

[snippers]


The reason I wrote that it would be nice to be able to write

if x is not empty:

is that it reads naturally.


[and more snippers]

Reads naturally?  For whom?  Readability counts does not mean make it 
sound like english as much as possible.  There are good reasons for not 
having computer languages written in human language.  If that's really 
what you want, go join Dave Parker and Flaming Thunder.  Or write that 
preprocessor that someone keeps yammering about and have it take code 
the way you want to write it and convert it to actual Python.  Would be 
an interesting experiment, anyway.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Russ P.
On Jul 30, 8:24 pm, Russ P. [EMAIL PROTECTED] wrote:
 On Jul 30, 8:03 pm, Erik Max Francis [EMAIL PROTECTED] wrote:

  Russ P. wrote:
   The reason I wrote that it would be nice to be able to write

   if x is not empty:

   is that it reads naturally. It was not an actual proposal, and the
   fact that you took it as such was *your* mistake.
  ...
   Now read carefully: I DID NOT CLAIM THAT THIS IS THE WAY TO DO IT! Let
   me repeat that for you: I DID NOT CLAIM THAT THIS IS THE WAY TO DO IT!
   Did you get that, idiot?

  So people who can read words but not minds are idiots.  Go get 'em, tiger!

 I don't know if you can read minds, but you seem to have a lot of
 trouble reading words.

 Can you read it would be nice to be able to write ...? Can you
 understand what it means? Can you understand that it does *not* mean,
 one *should* be able to write ...?

 The really significant question here is why I waste my valuable time
 with pedants like you.

Folks, I'm sorry for being so harsh here. But this guy keeps insisting
that I dispayed a fundamental lack of understanding of the correct
usage of is in Python. If that were true, I would have gladly
admitted it and dropped the matter. But it is completely false. The
simple fact is that I fully understood how is works in Python from
the first time I read about it -- as I'm sure most others here did
too. It just gets my goat that someone would latch onto some whimsical
suggestion I wrote to try to prove otherwise.

He did not need to play that silly little game, and he could have
easily avoided my insults had he not played it.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Erik Max Francis

Russ P. wrote:


I don't know if you can read minds, but you seem to have a lot of
trouble reading words.

Can you read it would be nice to be able to write ...? Can you
understand what it means? Can you understand that it does *not* mean,
one *should* be able to write ...?


You're sure going on about a distinction without a difference for a guy 
who childishly likes to call other people names.  A reasonable person 
would have long ago moved on instead of blaming others for not 
immediately intuiting your thoughts, rather than straightforwardly 
reading your words.  Which, by the way, includes at least three people 
other than myself.


But I'll bet the mindless namecalling is really working out for you. 
Go, team, go!


--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  You are my martyr / I'm a vestige of a revolution
   -- Lamya
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread alex23
Ethan Furman wrote:
 If that's really what you want, go join Dave Parker and Flaming Thunder.

Best recommendation in this thread to date :)
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Russ P.
On Jul 30, 9:27 pm, Erik Max Francis [EMAIL PROTECTED] wrote:
 Russ P. wrote:
  I don't know if you can read minds, but you seem to have a lot of
  trouble reading words.

  Can you read it would be nice to be able to write ...? Can you
  understand what it means? Can you understand that it does *not* mean,
  one *should* be able to write ...?

 You're sure going on about a distinction without a difference for a guy
 who childishly likes to call other people names.  A reasonable person
 would have long ago moved on instead of blaming others for not
 immediately intuiting your thoughts, rather than straightforwardly
 reading your words.  Which, by the way, includes at least three people
 other than myself.

 But I'll bet the mindless namecalling is really working out for you.
 Go, team, go!

You earned the childish name calling by acting like a child -- with
your petty little game of trying to show that I don't understand a
basic concept in Python. As I said, your initial misunderstanding,
while silly, was at least forgivable. But your insistence on repeating
it time after time is not. It is truly pathetic.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-30 Thread Erik Max Francis

Russ P. wrote:


On Jul 30, 9:27 pm, Erik Max Francis [EMAIL PROTECTED] wrote:

You're sure going on about a distinction without a difference for a guy
who childishly likes to call other people names.  A reasonable person
would have long ago moved on instead of blaming others for not
immediately intuiting your thoughts, rather than straightforwardly
reading your words.  Which, by the way, includes at least three people
other than myself.

But I'll bet the mindless namecalling is really working out for you.
Go, team, go!


You earned the childish name calling by acting like a child -- with
your petty little game of trying to show that I don't understand a
basic concept in Python. As I said, your initial misunderstanding,
while silly, was at least forgivable. But your insistence on repeating
it time after time is not. It is truly pathetic.


Sis, boom, rah rah rah!

You're kind of skipping over the point where three other people had the 
same misunderstanding about your original statement and correction, so 
maybe the reader is not the problem but rather the writer, but hey, 
don't let that get in the way of a good public shitfit.


You're winning!

--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  I am not a Virginian, but an American.
   -- Patrick Henry
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Carl Banks
On Jul 28, 8:15 pm, Steven D'Aprano [EMAIL PROTECTED]
cybersource.com.au wrote:
 On Mon, 28 Jul 2008 13:22:37 -0700, Carl Banks wrote:
  On Jul 28, 10:00 am, Steven D'Aprano [EMAIL PROTECTED]
  cybersource.com.au wrote:
  Cutting to the crux of the discussion...

  On Sun, 27 Jul 2008 23:45:26 -0700, Carl Banks wrote:
   I want something where if x will do but a simple explicit test
   won't.

  Explicit tests aren't simple unless you know what type x is. If x could
  be of any type, you can't write a simple test. Does x have a length? Is
  it a number? Maybe it's a fixed-length circular length, and the length
  is non-zero even when it's empty? Who knows? How many cases do you need
  to consider?

  Use case, please.  I'm asking for code, not arguments.  Please give me a
  piece of code where you can write if x that works but a simple
  explicit test won't.

 I gave you a piece of code, actual code from one of my own projects. If
 you wouldn't accept that evidence then, why would you accept it now?

I would accept as evidence something that satisfies my criteria,
which your example did not: it could have easily (and more robustly)
been written with a simple explicit test.  I am looking for one that
can't.

You keep bringing up this notion of more complex with no benefit,
which I'm simply not interested in talking about that at this time,
and I won't respond to any of your points.  I am seeking the answer to
one question: whether if x can usefully do something a simple
explicit test can't.  Everyone already knows that if x requires
fewer keystrokes and parses to fewer nodes.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Heiko Wundram
Am Dienstag, 29. Juli 2008 10:37:45 schrieb Carl Banks:
 You keep bringing up this notion of more complex with no benefit,
 which I'm simply not interested in talking about that at this time,
 and I won't respond to any of your points.  I am seeking the answer to
 one question: whether if x can usefully do something a simple
 explicit test can't.  Everyone already knows that if x requires
 fewer keystrokes and parses to fewer nodes.

Yes, there are quite a lot of use cases. Think of a polymorphic function, 
where the input can be any object that implements the iterator protocol 
(concerning base types, I'm thinking of strings, tuples, lists, dicts and 
sets here, which are all iterable and yield a chain of singular values) and 
you want to check whether the iterable object is empty or not for 
special-casing that.

if x uses the special interface method __nonzero__() if that's implemented 
(which all of the above types implement as returning True iff the container 
yields at least one value when iterated over, i.e., it isn't empty), and 
falls back to a test for __len__() != 0, otherwise x is considered to be 
true.

Now, explicitly comparing x against the five empty values of the container 
types I specified above would be broken design in such a function: when I 
implement a container class myself, which implements the __iter__() and 
__nonzero__() methods, I can directly use it with the polymorphic function I 
wrote, and the special case for an empty container will work out of the box. 
In the case of explicit comparisons, I have to modify the polymorphic 
function to accept my container type in addition to those it already 
processes to be able to special-case the empty container for my type.

I can't dig up a simple example from code I wrote quickly, but because of the 
fact that explicit comparisons always hamper polymorphism (which might not be 
needed initially, but you never know what comes up later, thinking of 
reusability of components), I personally always stick to the idiom if x 
rather than comparing it to an empty value, even when I'm sure that the type 
of x is a singular type.

Additionally, IMHO if x is so much more readable than if x != something.

Just my 2 (euro)cents.

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Steven D'Aprano
On Tue, 29 Jul 2008 01:37:45 -0700, Carl Banks wrote:

 On Jul 28, 8:15 pm, Steven D'Aprano [EMAIL PROTECTED]
 cybersource.com.au wrote:
 On Mon, 28 Jul 2008 13:22:37 -0700, Carl Banks wrote:
  On Jul 28, 10:00 am, Steven D'Aprano [EMAIL PROTECTED]
  cybersource.com.au wrote:
  Cutting to the crux of the discussion...

  On Sun, 27 Jul 2008 23:45:26 -0700, Carl Banks wrote:
   I want something where if x will do but a simple explicit test
   won't.

  Explicit tests aren't simple unless you know what type x is. If x
  could be of any type, you can't write a simple test. Does x have a
  length? Is it a number? Maybe it's a fixed-length circular length,
  and the length is non-zero even when it's empty? Who knows? How many
  cases do you need to consider?

  Use case, please.  I'm asking for code, not arguments.  Please give
  me a piece of code where you can write if x that works but a simple
  explicit test won't.

 I gave you a piece of code, actual code from one of my own projects. If
 you wouldn't accept that evidence then, why would you accept it now?
 
 I would accept as evidence something that satisfies my criteria, which
 your example did not: it could have easily (and more robustly) been
 written with a simple explicit test.

Only at the cost of completely ignoring the functional requirements and 
changing the API. In other words: you ignore my code, and invent your own 
imaginary code that does something completely different, then say that 
this imaginary code is better.

And I question your assertion that a simple explicit test is more 
robust. Where's your evidence for that?



 I am looking for one that can't.

If you are writing code that needs to do the right thing with arbitrary 
types, then your so-called simple explicit tests simply can't work. If 
your code isn't expected to deal with arbitrary types, then you've got an 
excellent chance that it will work, because you know what types to expect.

Until somebody passes a type that you didn't expect, and your code fails 
because it makes assumptions about the object.

If you know that you only get lists, then if len(x)!=0 is a perfectly 
good test (apart from being longer to type, harder to read, and slower to 
execute than if x). It will work so long as you only get objects where 
a length of zero is equivalent to being false. That's a good assumption 
to make, but it is an *unnecessary* assumption. Any reasonable object you 
get will know if it is false/nothing or true/something, so why make any 
assumptions? Just ask the object. It knows.


 
 You keep bringing up this notion of more complex with no benefit,
 which I'm simply not interested in talking about that at this time, and
 I won't respond to any of your points.

Of course not.



 I am seeking the answer to one
 question: whether if x can usefully do something a simple explicit
 test can't.

if x is completely type agnostic. You can pass an object of any type to 
it, and it will work. (Excluding objects with buggy methods, naturally.)

Try doing that with one of your so-called simple explicit tests.



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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Anders J. Munch

Steven D'Aprano wrote:

On Tue, 29 Jul 2008 00:23:02 +, Steven D'Aprano wrote:


Dude. Dude. Just... learn some Python before you embarrass yourself
further.



I'm sorry Anders, that was a needlessly harsh thing for me to say. I 
apologize for the unpleasant tone. 

Still, __nonzero__ is a fundamental part of Python's behaviour. You 
should learn about it.


Hm, first you apologize, then you repeat the insult?  That's no basis for a 
conversation.  Bye from here.


regards, Anders
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Heiko Wundram
Am Dienstag, 29. Juli 2008 11:15:05 schrieb Heiko Wundram:
 I can't dig up a simple example from code I wrote quickly...

Just to get back to that: an example I found where if x (the generic 
__nonzero__() test) will work to test for emptiness/non-emptiness of a 
container, whereas if len(x)  0 (the specific test for this example) 
will not, is my for own integer set type I wrote a while back (which you can 
find on ASPN).

The corresponding set type allows you to create infinitely sized sets of 
integers (which of course are stored as pairs of start,stop-values, so 
the storage itself for the set is bounded), for which len(x) does not have 
a proper meaning anymore, and __len__() is limited to returning a (platform 
dependent) ssize_t anyway IIRC, so even with a bounded set, the length of the 
set might not necessarily be accessible using len(x); that's why the set type 
additionally got a member function called .len() to work around this 
restriction.

I should think is a non-contrieved example where the generic test whether the 
object considers itself True/False (which for containers means 
non-empty/empty) is preferrable over the special case test whether the length 
is positive. A polymorphic function, which for example only accesses the 
first ten members of the container is able to work with an infinite set if it 
uses the generic test, but is not in case it uses len(x)  0.

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Colin J. Williams

Heiko Wundram wrote:

Am Dienstag, 29. Juli 2008 11:15:05 schrieb Heiko Wundram:

I can't dig up a simple example from code I wrote quickly...


Just to get back to that: an example I found where if x (the generic 
__nonzero__() test) will work to test for emptiness/non-emptiness of a 
container, whereas if len(x)  0 (the specific test for this example) 
will not, is my for own integer set type I wrote a while back (which you can 
find on ASPN).


The corresponding set type allows you to create infinitely sized sets of 
integers (which of course are stored as pairs of start,stop-values, so 
the storage itself for the set is bounded), for which len(x) does not have 
a proper meaning anymore, and __len__() is limited to returning a (platform 
dependent) ssize_t anyway IIRC, so even with a bounded set, the length of the 
set might not necessarily be accessible using len(x); that's why the set type 
additionally got a member function called .len() to work around this 
restriction.


I should think is a non-contrieved example where the generic test whether the 
object considers itself True/False (which for containers means 
non-empty/empty) is preferrable over the special case test whether the length 
is positive. A polymorphic function, which for example only accesses the 
first ten members of the container is able to work with an infinite set if it 
uses the generic test, but is not in case it uses len(x)  0.


(+1)  This an Heiko's previous post sets 
things out clearly.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Matthew Fitzgibbons

Carl Banks wrote:

On Jul 28, 8:15 pm, Steven D'Aprano [EMAIL PROTECTED]
cybersource.com.au wrote:

On Mon, 28 Jul 2008 13:22:37 -0700, Carl Banks wrote:

On Jul 28, 10:00 am, Steven D'Aprano [EMAIL PROTECTED]
cybersource.com.au wrote:

Cutting to the crux of the discussion...
On Sun, 27 Jul 2008 23:45:26 -0700, Carl Banks wrote:

I want something where if x will do but a simple explicit test
won't.

Explicit tests aren't simple unless you know what type x is. If x could
be of any type, you can't write a simple test. Does x have a length? Is
it a number? Maybe it's a fixed-length circular length, and the length
is non-zero even when it's empty? Who knows? How many cases do you need
to consider?

Use case, please.  I'm asking for code, not arguments.  Please give me a
piece of code where you can write if x that works but a simple
explicit test won't.

I gave you a piece of code, actual code from one of my own projects. If
you wouldn't accept that evidence then, why would you accept it now?


I would accept as evidence something that satisfies my criteria,
which your example did not: it could have easily (and more robustly)
been written with a simple explicit test.  I am looking for one that
can't.

You keep bringing up this notion of more complex with no benefit,
which I'm simply not interested in talking about that at this time,
and I won't respond to any of your points.  I am seeking the answer to
one question: whether if x can usefully do something a simple
explicit test can't.  Everyone already knows that if x requires
fewer keystrokes and parses to fewer nodes.


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



My use case involves a DAG of filters that pass data (of a variety of 
types--filters just pass on data types they don't understand) between 
them. I can also drop out of the filter chain at any point, using 
critera determined by the filters. These criteria, you guessed it, are 
bound to __nonzero__ in the filter and I determine whether or not to 
continue through the graph using if x. You can't code explicit tests 
if you don't know what the tests even are beforehand. Also, I wanted to 
support builtins (ints and lists in particular) because they can be 
meaningful inputs to filters. Finally, as I add more filters and data 
types, I don't want to go back and mess with the code that decides 
whether or not to break out of the graph.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Carl Banks
On Jul 29, 5:27 am, Steven D'Aprano
[EMAIL PROTECTED] wrote:
 On Tue, 29 Jul 2008 01:37:45 -0700, Carl Banks wrote:
  I am looking for one that can't.

 If you are writing code that needs to do the right thing with arbitrary
 types, then your so-called simple explicit tests simply can't work.

I asked for a code example.  You say this is true, but neither you nor
anyone else here has provided useful code that demonstrates it.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Carl Banks
On Jul 29, 5:15 am, Heiko Wundram [EMAIL PROTECTED] wrote:
 I can't dig up a simple example from code I wrote quickly, but because of the
 fact that explicit comparisons always hamper polymorphism

I'm not going to take your word for it.  Do you have code that
demonstrates how if x improves polymorphism relative to simple
explicit tests?


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Carl Banks
On Jul 29, 11:12 am, Matthew Fitzgibbons [EMAIL PROTECTED] wrote:
 Carl Banks wrote:
  On Jul 28, 8:15 pm, Steven D'Aprano [EMAIL PROTECTED]
  cybersource.com.au wrote:
  On Mon, 28 Jul 2008 13:22:37 -0700, Carl Banks wrote:
  On Jul 28, 10:00 am, Steven D'Aprano [EMAIL PROTECTED]
  cybersource.com.au wrote:
  Cutting to the crux of the discussion...
  On Sun, 27 Jul 2008 23:45:26 -0700, Carl Banks wrote:
  I want something where if x will do but a simple explicit test
  won't.
  Explicit tests aren't simple unless you know what type x is. If x could
  be of any type, you can't write a simple test. Does x have a length? Is
  it a number? Maybe it's a fixed-length circular length, and the length
  is non-zero even when it's empty? Who knows? How many cases do you need
  to consider?
  Use case, please.  I'm asking for code, not arguments.  Please give me a
  piece of code where you can write if x that works but a simple
  explicit test won't.
  I gave you a piece of code, actual code from one of my own projects. If
  you wouldn't accept that evidence then, why would you accept it now?

  I would accept as evidence something that satisfies my criteria,
  which your example did not: it could have easily (and more robustly)
  been written with a simple explicit test.  I am looking for one that
  can't.

  You keep bringing up this notion of more complex with no benefit,
  which I'm simply not interested in talking about that at this time,
  and I won't respond to any of your points.  I am seeking the answer to
  one question: whether if x can usefully do something a simple
  explicit test can't.  Everyone already knows that if x requires
  fewer keystrokes and parses to fewer nodes.

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

 My use case involves a DAG of filters that pass data (of a variety of
 types--filters just pass on data types they don't understand) between
 them. I can also drop out of the filter chain at any point, using
 critera determined by the filters. These criteria, you guessed it, are
 bound to __nonzero__ in the filter and I determine whether or not to
 continue through the graph using if x. You can't code explicit tests
 if you don't know what the tests even are beforehand. Also, I wanted to
 support builtins (ints and lists in particular) because they can be
 meaningful inputs to filters. Finally, as I add more filters and data
 types, I don't want to go back and mess with the code that decides
 whether or not to break out of the graph.

Much like in Steven D'Aprano's example, still the only actual code
snippet I've seen, it seems that this can easily be done with a simple
explicit test by having all no-advance filters return None and testing
with if x is not None.  So it doesn't pass my criterion of being not
replaceable with simple explicit test.

Maybe that's not workable for some reason.  Perhaps if you'd post a
code example that shows this, rather than just talking about it, you
might be more persuasive.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Carl Banks
On Jul 29, 1:30 pm, Carl Banks [EMAIL PROTECTED] wrote:
 On Jul 29, 5:15 am, Heiko Wundram [EMAIL PROTECTED] wrote:

  I can't dig up a simple example from code I wrote quickly, but because of 
  the
  fact that explicit comparisons always hamper polymorphism

 I'm not going to take your word for it.  Do you have code that
 demonstrates how if x improves polymorphism relative to simple
 explicit tests?

And, in case it wasn't obvious, the way to demonstrate that if x
improves polymorphism relative to simple explicit tests would be
posting an example where if x works but a simple explicit test
doesn't.  So don't accuse me of changing the question on you: it's the
same question.

You see, what you are stating and expecting me to take for granted is
exactly what I'm asking for a concrete example of.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Carl Banks
On Jul 29, 5:27 am, Steven D'Aprano
[EMAIL PROTECTED] wrote:
 On Tue, 29 Jul 2008 01:37:45 -0700, Carl Banks wrote:
  I would accept as evidence something that satisfies my criteria, which
  your example did not: it could have easily (and more robustly) been
  written with a simple explicit test.

 Only at the cost of completely ignoring the functional requirements and
 changing the API. In other words: you ignore my code, and invent your own
 imaginary code that does something completely different, then say that
 this imaginary code is better.

And, BTW, you keep making unsubstantiated assertions and keep
expecting me to take them at face value.  I'm really not going to take
your word for it that your functional requirements would preclude
the possibility of rewriting it as I said to, unless you provide
details.

Also, your third claim is false since it would have exactly the same
behavior.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Erik Max Francis

Carl Banks wrote:

On Jul 29, 1:30 pm, Carl Banks [EMAIL PROTECTED] wrote:

On Jul 29, 5:15 am, Heiko Wundram [EMAIL PROTECTED] wrote:


I can't dig up a simple example from code I wrote quickly, but because of the
fact that explicit comparisons always hamper polymorphism

I'm not going to take your word for it.  Do you have code that
demonstrates how if x improves polymorphism relative to simple
explicit tests?


And, in case it wasn't obvious, the way to demonstrate that if x
improves polymorphism relative to simple explicit tests would be
posting an example where if x works but a simple explicit test
doesn't.  So don't accuse me of changing the question on you: it's the
same question.


It's pretty elementary, and people thought just describing the issue of 
polymorphism and duck-typing was sufficient to explain it.  Since it 
apparently isn't:


Let's say you come up with some kind of custom sequence class.  You want 
to act like any native sequence type (list, tuple, array, string, etc.) 
in all reasonable ways (length testing, iteration, indexing, etc.) so 
that it can be used in place of these things in code that doesn't 
require explicit types.  You know, standard polymorphism and duck-typing.


So you want a test for whether your custom sequence isn't empty.  To 
create an simple, explicit test would be defined an `isntEmpty` method 
that you can call, like so:


if myObject.isntEmpty():
# then do something

However, this wouldn't be polymorphic since now someone would have to 
call a simple, explicit test that doesn't exist on all the other 
sequence-like objects.  Therefore, you've broken polymorphism.


The solution is to override the `__nonzero__` method so that you can use 
Boolean testing, just like all the other sequence-like objects:


if myObject:
# then do the same thing

Now people who use your custom sequence type don't have to write special 
code, and code written to deal with sequences using duck typing (which 
is typically nearly all Python code) don't have to know anything special 
about your custom sequence class.


--
Erik Max Francis  [EMAIL PROTECTED]  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM, Y!M erikmaxfrancis
  Everything's gonna be all right / Everything's gonna be okay
   -- Sweetbox
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Matthew Woodcraft
Steven D'Aprano  [EMAIL PROTECTED] wrote:
 if x is completely type agnostic. You can pass an object of any type to 
 it, and it will work. (Excluding objects with buggy methods, naturally.)

There are many circumstances where if a parameter is None I'd rather
get an exception than have the code carry on with the 'empty container'
branch (and silently give me a meaningless result).

-M-

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Heiko Wundram

Am 29.07.2008, 18:30 Uhr, schrieb Carl Banks [EMAIL PROTECTED]:


On Jul 29, 5:15 am, Heiko Wundram [EMAIL PROTECTED] wrote:
I can't dig up a simple example from code I wrote quickly, but because  
of the

fact that explicit comparisons always hamper polymorphism


I'm not going to take your word for it.  Do you have code that
demonstrates how if x improves polymorphism relative to simple
explicit tests?


As I wrote in the second reply email I sent, check out my integer set  
recipe on ASPN (and to save you the search:  
http://code.activestate.com/recipes/466286/). To test whether the integer  
set is empty or not (in a polymorphic function which accepts any kind of  
sequence type), the explicit test would be, as you proposed elsewhere:  
len(x)  0. This simply WILL NOT work with some sets of that respective  
type, because, as I documented for the __len__() method there: the return  
value of __len__() has to (had to?) be in the range 0 = len  2**31  
(which I think means, as I tested and implemented it on i386, that the  
return value has to fit in an ssize_t platform type, but someone with more  
knowledge of the interpreter internals might be able to comment here; I'm  
not in the mood for checking this out now).


Another reason why the test for __nonzero__() is beneficial, at least  
here: testing whether the set is empty or not is easy, because an empty  
set has no ranges, and a set with at least one element has at least one  
range (i.e., to test whether the set is non-empty, check whether the  
_ranges member, a list, is __nonzero__()); taking the len() of a set  
always means adding the size of the ranges together (even though this  
could of course be precomputed/cached, as the set type is immutable, but  
I'm not doing that in that recipe's code).


So, adding things up: the interpretation of __nonzero__(), i.e. the direct  
conversion to bool, for container-types, implements THE means to test  
whether the container is empty or not. Insisting on not using it, because  
a simple explicit test is supposedly better, will prove to not work in  
those cases where the container type might not have a representable length  
(because of the constraints on the return value of __len__()), even though  
the container has an empty/non-empty state.


I think this does make a very compelling use case for if x instead of  
if len(x)  0.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Carl Banks
On Jul 29, 4:08 pm, Erik Max Francis [EMAIL PROTECTED] wrote:
 Carl Banks wrote:
  On Jul 29, 1:30 pm, Carl Banks [EMAIL PROTECTED] wrote:
  On Jul 29, 5:15 am, Heiko Wundram [EMAIL PROTECTED] wrote:

  I can't dig up a simple example from code I wrote quickly, but because of 
  the
  fact that explicit comparisons always hamper polymorphism
  I'm not going to take your word for it.  Do you have code that
  demonstrates how if x improves polymorphism relative to simple
  explicit tests?

  And, in case it wasn't obvious, the way to demonstrate that if x
  improves polymorphism relative to simple explicit tests would be
  posting an example where if x works but a simple explicit test
  doesn't.  So don't accuse me of changing the question on you: it's the
  same question.

 It's pretty elementary, and people thought just describing the issue of
 polymorphism and duck-typing was sufficient to explain it.  Since it
 apparently isn't:

 Let's say you come up with some kind of custom sequence class.  You want
 to act like any native sequence type (list, tuple, array, string, etc.)
 in all reasonable ways (length testing, iteration, indexing, etc.) so
 that it can be used in place of these things in code that doesn't
 require explicit types.  You know, standard polymorphism and duck-typing.

 So you want a test for whether your custom sequence isn't empty.  To
 create an simple, explicit test would be defined an `isntEmpty` method
 that you can call, like so:

 if myObject.isntEmpty():
 # then do something

 However, this wouldn't be polymorphic since now someone would have to
 call a simple, explicit test that doesn't exist on all the other
 sequence-like objects.  Therefore, you've broken polymorphism.

 The solution is to override the `__nonzero__` method so that you can use
 Boolean testing, just like all the other sequence-like objects:

 if myObject:
 # then do the same thing

 Now people who use your custom sequence type don't have to write special
 code, and code written to deal with sequences using duck typing (which
 is typically nearly all Python code) don't have to know anything special
 about your custom sequence class.

Bzzt.  if len(x)!=0 is a simple explicit that would work for this
class and all built-in containers. (Or should--Steven D'Aprano's
objections notwithstanding, any reasonable container type should
support this invariant.  From a language design standpoint, an empty
builtin could have been created to simplify this even more, but since
there isn't one len(x)!=0 will have to do.)

Let me reframe the question to see if we can make some headway.

The vast majority of true/false tests fit into one of the following
four categories:

1. Testing the explicit result of a boolean operation (obviously)
2. Testing whether a numeric type is nonzero.
3. Testing whether a container type is empty.
4. Testing whether you have a (non-numeric, non-container) object of
some sort, or None.

There's a few other cases, but let's start with these to keep things
simple and add other cases as necessary.

We already know that cases 2, 3, and 4 can, individually, be converted
to a simple explicit test (using x!=0, len(x)!=0, and x is not None,
respectively).  As long as you know which kind of object you're
expecting, you can convert the implicit to an explicit test.

Now, you guys keep whining But what if you don't know what kind of
object you're expecting?!!  It's a fair question, and my belief is
that, in practice, this almost never happens.  Duck typing happens
between numeric types often, and between container types often, but
almost never between both numeric and container types.  Their usages
are simply too different.

So I present another question to you: Give me an useful, non-trivial,
example of some code that where x could be either a numeric or
container type.  That would be the first step to finding a
counterexample.  (The next step would be to show that it's useful to
use if x in such a context.)


Once again, I'm invoking the contraint against simply using x in a
boolean context, or passing x to a function expecting a boolean
doesn't count, since in those cases x can be set to the result of the
explicit test.  So none of this:

def nand(a,b): return not (a and b)

Or anything trivial like this:

def add(a,b): return a+b


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Carl Banks
On Jul 29, 3:43 pm, Heiko Wundram [EMAIL PROTECTED] wrote:
 Am 29.07.2008, 18:30 Uhr, schrieb Carl Banks [EMAIL PROTECTED]:

  On Jul 29, 5:15 am, Heiko Wundram [EMAIL PROTECTED] wrote:
  I can't dig up a simple example from code I wrote quickly, but because
  of the
  fact that explicit comparisons always hamper polymorphism

  I'm not going to take your word for it.  Do you have code that
  demonstrates how if x improves polymorphism relative to simple
  explicit tests?

 As I wrote in the second reply email I sent, check out my integer set
 recipe on ASPN (and to save you the search:  
 http://code.activestate.com/recipes/466286/).

Couple points:

1. Any container type that returns a length that isn't exactly the
number of elements in it is broken.
2. The need for __nonzero__ in this case depends on a limitation in
the language.
3. On the other hand, I will concede that sometimes calculating len is
a lot more expensive than determining emptiness, and at a basic level
it's important to avoid these costs.  You have found a practical use
case for __nonzero__.

However, I'd like to point out the contrasting example of numpy
arrays.  For numpy arrays, if x fails (it raises an exception) but
if len(x)!=0 succeeds.

The only sane advice for dealing with nonconformant classes like numpy
arrays or your interger set is to be wary of nonconformances and don't
expect polymorphism to work all the time.

So I guess I'll concede that in the occasional cases with
nonconformant classes the if x might help increase polymorphism a
little.

(BTW: here's another little thing to think about: the if x is useful
here only because there isn't an explicit way to test emptiness
without len.)

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread giltay
On Jul 29, 1:30 pm, Carl Banks [EMAIL PROTECTED] wrote:
 On Jul 29, 5:15 am, Heiko Wundram [EMAIL PROTECTED] wrote:

  I can't dig up a simple example from code I wrote quickly, but because of 
  the
  fact that explicit comparisons always hamper polymorphism

 I'm not going to take your word for it.  Do you have code that
 demonstrates how if x improves polymorphism relative to simple
 explicit tests?

 Carl Banks

I think if x works in some cases, but not in others.  Here's an
example I just made up and a counterexample from my own code.

Example:

Here's a function, print_members.  It's just something that takes some
iterable and prints its members in XML.  It's special-cased so that an
empty iterable gets an empty tag.  (This is a bit of a trivial
example, I admit; the point is that the empty iterable is a special
case.)

def print_members(iterable):
if not iterable:
print 'members /'
return
print 'members'
for item in iterable:
print 'item%s/item' % item
print '/members'

 print_members(['a', 'b', 'c'])

members
itema/item
itemb/item
itemc/item
/members

 print_members([])

members /

I could have used if len(iterable) == 0: for these cases, but only
because the length of a list means something.  Say I were to implement
a matrix class.  The length of a matrix isn't well-defined, so I won't
implement __len__.  I will, however, implement __nonzero__, since if
it has no members, it's empty.

class SimpleMatrix(object):

def __init__(self, *rows):
self.rows = rows

def __nonzero__(self):
for row in self.rows:
if row:
return True
return False

def __iter__(self):
return iter(sum(self.rows, []))

 a = SimpleMatrix([1, 2, 3], [4, 5, 6])
 print_members(a)

members
item1/item
item2/item
item3/item
item4/item
item5/item
item6/item
/members

 b = SimpleMatrix([],[],[])
 len(b)

Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: object of type 'SimpleMatrix' has no len()

 print_members(b)

members /

So print_members can work on iterables that have no len(), and handle
the special case of an empty iterable, as long as __nonzero__ is
implemented.

Counterexample:

While if x works well in some circumstances, I don't like using it
for purely numeric types.  For instance, I have a mutable Signal class
for doing some basic DSP.  Among other things, I can apply a DC offset
to the signal (it just adds the offset to all the samples).  I have a
special case for an offset of 0 so I don't have to loop through all
the samples (I also have a two-pass remove_offset method that
subtracts the average; if it's already properly centred, I can skip a
step).

class Signal:
[...]
def dc_offset(self, amount):
if amount == 0:
return
self.samples = [sample + amount for sample in self.samples]

Here, if amount == 0 is deliberate.  At no point should I be adding
an offset that's a list or a dict, even an empty one.
Signal.dc_offset should raise an exception if I try to do that,
because that indicates there's a bug somewhere.  If I do pass in [] or
{}, that test will fail, and it will try to add the list or dict to
the samples, at which point I get a TypeError.

Geoff G-T

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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Heiko Wundram

Also, just a couple of points:

Am 29.07.2008, 22:27 Uhr, schrieb Carl Banks [EMAIL PROTECTED]:

1. Any container type that returns a length that isn't exactly the
number of elements in it is broken.


I agree, but how do you ever expect to return an infinite element count?  
The direction I took in that recipe was not returning some magic value  
but raising an OverflowError (for example, you could've also cropped the  
length at 2**31-1 as meaning anything equal to or larger). This is the  
thing that breaks your explicit test for non-emptyness using len(x)  0,  
but it's also the only possible thing to do if you want to return the  
number of elements exactly where possible and inform the user when not  
(and OverflowError should make the point clear).


Anyway, that's why there is a separate member function which is explicitly  
documented to return a magic value in case of an infinite set (i.e., -1)  
and an exact element count otherwise, but using that (you could write  
x.len() != 0 for the type in question to test for non-emptiness) breaks  
polymorphism.



2. The need for __nonzero__ in this case depends on a limitation in
the language.


True, but only for sets with are finite. For an infinite set, as I said  
above: what would you want __len__() to return? There is no proper  
interpretation of __len__() for an infinite set, even though the set is  
non-empty, except if you introduced the magic value infinity into Python  
(which I did as -1 for my personal length protocol).



3. On the other hand, I will concede that sometimes calculating len is
a lot more expensive than determining emptiness, and at a basic level
it's important to avoid these costs.  You have found a practical use
case for __nonzero__.


This is just a somewhat additional point I was trying to make; the main  
argument are the two points you see above.



However, I'd like to point out the contrasting example of numpy
arrays.  For numpy arrays, if x fails (it raises an exception) but
if len(x)!=0 succeeds.

The only sane advice for dealing with nonconformant classes like numpy
arrays or your interger set is to be wary of nonconformances and don't
expect polymorphism to work all the time.


The thing is: my integer set type IS conformant to the protocols of all  
other sequence types that Python offers directly, and as such can be used  
in any polymorphic function that expects a sequence type and doesn't test  
for the length (because of the obvious limitation that the length might  
not have a bound), but only for emptiness/non-emptiness. It's the numpy  
array that's non-conformant (at least from what you're saying here; I  
haven't used numpy yet, so I can't comment).



So I guess I'll concede that in the occasional cases with
nonconformant classes the if x might help increase polymorphism a
little.

(BTW: here's another little thing to think about: the if x is useful
here only because there isn't an explicit way to test emptiness
without len.)


The thing being, again, as others have already stated: __nonzero__() IS  
the explicit way to test non-emptiness of a container (type)! If I wanted  
to make things more verbose, I'd not use if len(x)0, but if bool(x)  
anyway, because casting to a boolean calls __nonzero__(). if len(x)0  
solves a different problem (even though in set theory the two are  
logically similar), and might not apply to all container types because of  
the restrictions on the return value of __len__(), which will always exist.


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


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Matthew Fitzgibbons

Carl Banks wrote:

On Jul 29, 11:12 am, Matthew Fitzgibbons [EMAIL PROTECTED] wrote:

Carl Banks wrote:

On Jul 28, 8:15 pm, Steven D'Aprano [EMAIL PROTECTED]
cybersource.com.au wrote:

On Mon, 28 Jul 2008 13:22:37 -0700, Carl Banks wrote:

On Jul 28, 10:00 am, Steven D'Aprano [EMAIL PROTECTED]
cybersource.com.au wrote:

Cutting to the crux of the discussion...
On Sun, 27 Jul 2008 23:45:26 -0700, Carl Banks wrote:

I want something where if x will do but a simple explicit test
won't.

Explicit tests aren't simple unless you know what type x is. If x could
be of any type, you can't write a simple test. Does x have a length? Is
it a number? Maybe it's a fixed-length circular length, and the length
is non-zero even when it's empty? Who knows? How many cases do you need
to consider?

Use case, please.  I'm asking for code, not arguments.  Please give me a
piece of code where you can write if x that works but a simple
explicit test won't.

I gave you a piece of code, actual code from one of my own projects. If
you wouldn't accept that evidence then, why would you accept it now?

I would accept as evidence something that satisfies my criteria,
which your example did not: it could have easily (and more robustly)
been written with a simple explicit test.  I am looking for one that
can't.
You keep bringing up this notion of more complex with no benefit,
which I'm simply not interested in talking about that at this time,
and I won't respond to any of your points.  I am seeking the answer to
one question: whether if x can usefully do something a simple
explicit test can't.  Everyone already knows that if x requires
fewer keystrokes and parses to fewer nodes.
Carl Banks
--
http://mail.python.org/mailman/listinfo/python-list

My use case involves a DAG of filters that pass data (of a variety of
types--filters just pass on data types they don't understand) between
them. I can also drop out of the filter chain at any point, using
critera determined by the filters. These criteria, you guessed it, are
bound to __nonzero__ in the filter and I determine whether or not to
continue through the graph using if x. You can't code explicit tests
if you don't know what the tests even are beforehand. Also, I wanted to
support builtins (ints and lists in particular) because they can be
meaningful inputs to filters. Finally, as I add more filters and data
types, I don't want to go back and mess with the code that decides
whether or not to break out of the graph.


Much like in Steven D'Aprano's example, still the only actual code
snippet I've seen, it seems that this can easily be done with a simple
explicit test by having all no-advance filters return None and testing
with if x is not None.  So it doesn't pass my criterion of being not
replaceable with simple explicit test.

Maybe that's not workable for some reason.  Perhaps if you'd post a
code example that shows this, rather than just talking about it, you
might be more persuasive.


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



The no-advance filters have to return the object because I don't just 
forget about it; I evaluate whether I pass it to the next filter or drop 
it in a completely different queue for use in the next stage of the 
operation. True means 'I'm ready to move on to the next stage,' False 
means 'Do the filter thing some more.'


Furthermore, the argument that I should just change my API to make a 
'simple test' work is not very convincing. The natural, obvious way for 
a filter to work is to pass through the data it operates on; why on 
Earth would it return None? I want to DO something with the data. In 
this case, make a decision about where to pass the data next. In Java, 
to accomplish this I would have to do lots of introspection and value 
checking (adding more any time I came up with a new kind of input), or 
make a new kind of interface that gives me a method so I can do a 
'simple test' (including wrappers for ints and arrays and anything else 
I decide to pass in down the road). But Python supports duck typing and 
gives me a handy __nonzero__ method; I can rebind __nonzero__ in my 
filters for my own classes, and ints and lists are handled how I want 
them to be by default. So why jump through hoops instead of just using 
'if x'?


I don't have any postable code (it's in a half way state and I haven't 
touched it for a while), but I'll see if I can't find the time to bang 
something up to give you the gist.


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


  1   2   >