
What Python learned from economics - naish
http://lazypython.blogspot.com/2008/11/what-python-learned-from-economics.html
======
marcus
There is a concept I've come to appreciate called "Code Debt", its the
technical liabilities you've accumulated through using shortcuts and bad
practices, things you've chosen to patch so they work in the short term but
will bite your ass in the long term and require much more effort to fix than
was originally saved.

Always remember the interest on Code Debt is brutal so the wise entrepreneur
strives to avoid it.

------
Jasber
I went through the presentation he references at
[http://python.net/%7Egoodger/projects/pycon/2007/idiomatic/p...](http://python.net/%7Egoodger/projects/pycon/2007/idiomatic/presentation.html):

A lot of what he says makes sense, but perhaps someone can explain why this is
wrong:

    
    
        def bad_append(new_item, a_list=[]):
            a_list.append(new_item)
            return a_list
    

and this is correct:

    
    
        def good_append(new_item, a_list=None):
            if a_list is None:
                a_list = []
            a_list.append(new_item)
            return a_list

~~~
mindslight
Expressions for default parameters are evaluated only once. So the default
a_list is _the same list_ on subsequent calls to bad_append

    
    
        good_append(1) -> [1]
        good_append(2) -> [2]
    
        bad_append(1) -> [1]
        bad_append(2) -> [1, 2]
    

Presumably, keeping an ever-growing shared list is not the desired behavior.

~~~
river_styx
Wow, is that by design? Why would you want such a side effect?

~~~
jerf
"Is that by design" - Well, yes and no. Try to forget the specific context for
the moment.

It is by design that the default parameter to a function parameter is
evaluated only once, as the alternative has bad performance implications.

It is by design that when you have a reference, that modifications to that
value are still available on the same reference. (That is, Python has mutable
objects with a couple of immutable exceptions.) This is obviously a fairly
normal choice, very basic to the language design.

Now, take these two normal things together and you get that if you make your
default function parameter a mutable object, it'll be the same mutable object
every time. The relevant "import this" aphorism would be "Special cases aren't
special enough to break the rules."

So, is this "by design"? Well, not _directly_ , it's a natural consequence of
other aspects of the design. All languages have corner cases of one sort or
another. Making this an exception would itself be a wart, after all:

    
    
          l = []
          def f(param = l): pass
          def g(param = []): pass
    

Shouldn't f and g have similar behavior? If you propose that the value be
evaluated every time, they won't, and then people would complain about that,
too.

~~~
mindslight
> It is by design that the default parameter to a function parameter is
> evaluated only once, as the alternative has bad performance implications.

Do people actually use the results of long-running or side-effectful functions
as default parameters? It seems the only time this issue comes up is when
people get tripped up by mutating simple [] or {} default parameters.

I would expect a default expression to be simple and pure. If this expression
should only be executed once, requiring a programmer to be explicit about the
complexity wouldn't be a bad thing.

~~~
etal
It can be a cute hack to get around the absence of static variables.

Lists have other quirks related to mutability; there are other obscure
Pythonisms that use this. If you want a nice magic-free immutable container,
tuples are a better bet.

------
Tichy
That concept only works as long as the makers of python really have found the
optimum way of doing things. It sounds like it could be stiffling innovation
to me. At the very least it doesn't encourage flexibility of the mind - rather
you are trained to believe that there is only one right way.

Also, the approach sounds familiar: didn't Java have the same rationale? And
of course Apple - to each their own, I guess (I don't like "the Apple way",
but others love it - probably would be the same with Python).

That article is really putting me off learning python, to be honest.

~~~
marcus
There is a python philosophy that says there should be one and preferably only
one obvious way to do things.

You can do things in a million different ways, monkey patch everything under
the sun but in the end, having just one way to do things makes code more
reliable and readable.

If you don't like the way the framework is built, and its one preferred way of
doing things, select a different framework or write your own. Trying to
undermine the assumptions of an existing framework has a tendency to cause
subtle hard to detect bugs. And trying to support all approaches tend to
create stuff that is bloated, ugly and slow.

~~~
d0mine
..having just one _obvious_ way to do things..

 _obvious_ is mandatory here.

------
cgranade
It seems like the author provides a counterexample in the article itself:
`from foo import *` doesn't at all enforce good coding habits. Now,
admittedly, Java (my language of choice) allows the same bad code, but it
still contradicts the idea that Python enforces long-term readability.

~~~
jerf
"import this": "Although practicality beats purity."

"from X import *" is for REPL usage, where it is damned handy, not to mention
a 20-line script. The community strongly discourages its use in big programs.

------
syntax-case
> Ultimately, this is why I like Python. The belief that best practices
> shouldn't be optional, and that they shouldn't be difficult creates a
> community where you actively want to go and learn from people's code.

This place I know was one of the earliest adopters of Python, and the code
they barfed up must be the buggiest, ugliest (GUI), slowest in its class
software I've ever seen. It's so buggy, it's insane: typos, calling methods
that don't exist, assuming arbitrary user input does not have 'keywords' in
them...

They couldn't write code in C, so they thought the problem was with the
language and switched to Python.

I say, lousy programmers, if they don't want to look for another occupation,
should stick with Java - at least the typos will be caught more frequently.

