PyWart: More surpises via "implict conversion to boolean" (and other steaming piles!)

Ned Batchelder ned at nedbatchelder.com
Mon Feb 10 14:17:33 EST 2014


On 2/10/14 1:45 PM, Rick Johnson wrote:
> ## START CODE ###########################################
> def foo():
>      # foo represents a patternless function
>      # or method that returns a Boolean value
>      # based on some internal test.
>      #
>      if 1==1:
>          return True
>      return False
> #
> # The fun begins when two tiny chars are forgotten,
> # however, since the code is legal, python will happily
> # give us the wrong answer.
> #
> if foo: # <- forgot parenthesis!
>      print 'implicit conversion to bool bites!'
> else:
>      #
>      # This block will NEVER execute because foo is
>      # ALWAYS True!
>      #
> #
> # Some introspection to understand why this happened.
> #
> print 'foo =', foo
> print 'bool(foo) ->', bool(foo)
> #
> ## END CODE #############################################
>
> It's obvious i did not follow the syntactical rules of
> Python, i understand that, however, there are three design
> flaws here that are contributing to this dilemma:
>
>      1. Implicit conversion to Boolean is evil
>
>      2. Conditionals should never accept parameter-less
>      functions. If you want to check if a callable is
>      True or False, then use "if bool(callable)". Any
>      usage of a bare callable in conditionals should
>      raise SyntaxError.
>
>      3. Implicit introspection is evil, i prefer all
>      references to a callable's names to result in a CALL
>      to that callable, not an introspection!
>      Introspection should ALWAYS be explicit!
>
> For a long time i thought Python's idea of a returning the
> value of a callable-- who's name is unadorned with "(...)"
> --was a good idea, however, i am now wholly convinced that
> this design is folly, and the reason is two fold:
>
>      1. Parenthesis should not be required for parameter-
>      less functions. I realize this is a bit more
>      complicated in languages like Python where
>      attributes are exposed to the public, but still, not
>      reason enough to require such onerous typing.
>
>      2. Implicit introspection is evil. I would prefer an
>      explicit method attached to all callables over a
>      sugar for "callable.call". We should never consume
>      syntactical sugars UNLESS they can greatly reduce
>      the density of code (like math operators for
>      instance!)
>

It seems like you are only looking at how to improve the error you just 
stumbled over, and not how the full proposal would work out, or even if 
you would like it better.

You haven't made the entire idea explicit yet.  How would I pass the 
function foo to another function?  The word "foo" now means, invoke foo. 
  You mean an explicit method attached to callables, like 
"foo.as_callable" ?   But why doesn't the word "foo" there invoke foo? 
Surely the word "as_callable" isn't special, so is it that 
"foo.anything" means direct attribute access on foo?  So to perform 
attribute access on the result of foo I need "foo().something" ?  In 
what cases does the word foo invoke the function, and when doesn't it?

It's not possible to make a programming language error-proof.  There 
will always be mistakes programmers can make.

-- 
Ned Batchelder, http://nedbatchelder.com




More information about the Python-list mailing list