On Mon, 10 Feb 2014 10:45:40 -0800, Rick Johnson wrote: > ## START CODE ########################################### > def foo(): > # foo represents a patternless function
Patternless? I have never heard that term before in this context. Do you mean a parameter-less or argument-less function? > # or method that returns a Boolean value > # based on some internal test. > # > if 1==1: > return True > return False This always returns True, since 1 always equals 1. > # 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!' No it doesn't. It rocks. You have found one tiny little disadvantage, about the size of a mote of dust floating: if you write functions that take no arguments (already a code-smell) and forget the brackets (mistakes will happen...) and have no tests to ensure that both branches of the `if` are tested (what, are you careless and negligent?), then you might be bitten by a bug of your own creation. Compared to that mote, the usefulness and convenience of duck-typing bools is about the size of Mt Everest. > else: > # > # This block will NEVER execute because foo is > # ALWAYS True! Correct. And since foo() is also always True, there is no difference. [...] > It's obvious i did not follow the syntactical rules of Python, i > understand that, No you don't understand that. You *did* follow the syntactical rules of Python. `if foo` is perfectly correct syntax, if it were not, you would have got a SyntaxError exception at compile-time. You need to understand the difference between syntax and semantics. This is invalid English syntax: "Cat mat on sat the." This is valid syntax, but semantically wrong: "The mat sat on the cat." This is both syntactically and semantically correct: "The cat sat on the mat." > however, there are three design flaws here that are > contributing to this dilemma: > > 1. Implicit conversion to Boolean is evil It's not implicit conversion. You're not understanding what is going on. foo is not converted to a bool, foo remains a function object. Rather, it's duck-typing truthiness, which is no different from any other duck- typing. If it swims like a bool and quacks like a bool, it might as well be a bool. Duck-typing is a design feature, not a flaw. > 2. Conditionals should never accept parameter-less functions. How is the conditional supposed to know that its term is a function? What's so special about parameter-less functions? You can forget to call functions with any number of parameters, especially if they take default values. Let's suppose that you get your way. Which of the following if-tests should be prohibited, and when should they be prohibited? At compile time? if random.random() > 0.5: spam = lambda x=23: x eggs = 42 else: spam = 42 eggs = lambda x=23: x if spam: print "spam is a truthy value" if eggs: print "eggs is a truthy value" > If you > want to check if a callable is True or False, then use "if > bool(callable)". Ewww. That's horrible. bool() should only be used to get a canonical bool object, e.g. for writing to a database or something. It should never be used just because you are scared of Python's power. > Any usage of a bare callable in conditionals should > raise SyntaxError. Ah, so it should happen at compile-time, not run-time? I'm afraid you're not as clear about how Python operates as you perhaps think you are. > 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! Again, this is a complete misunderstanding of Python's execution model. It is true that callables have names, but they are only used for displaying error messages in tracebacks. Otherwise, callables are no different from any other object: they can have zero, one or many names bound to them, and referring to the name gives you access to the object itself. spam = <any object at all, whether a function or not> spam # this is a reference to the object Introspection has nothing to do with this. > 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, Oh well, not everyone has the sense to recognise good design. You should do more Python programming, and less ranting, you might learn something. > and the > reason is two fold: > > 1. Parenthesis should not be required for parameter- less functions. Of course they should. Firstly, parameter-less functions are a code- smell, and ought to be discouraged. Secondly, even if you have a good reason for using one -- for example, random.random -- then the difference between referring to the object and calling the object should be clear. With Python's correct design, we have: spam # always, without exception, refers to the object spam() # always, without exception, calls the object With your suggested design, we would have: spam # sometimes refers to the object, sometimes calls the object spam() # always calls the object Ruby makes this mistake, and is a lessor language for it. > 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. What does the presence or absence of attributes have to do with this? > 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!) I do not understand what you are trying to say here. -- Steven -- https://mail.python.org/mailman/listinfo/python-list