En Thu, 23 Aug 2007 09:20:21 -0300, BJörn Lindqvist <[EMAIL PROTECTED]> escribi�:
> On 8/22/07, Gabriel Genellina <[EMAIL PROTECTED]> wrote: >> On 22 ago, 10:00, "BJörn Lindqvist" <[EMAIL PROTECTED]> wrote: >> > As I said, you can accomplish the exact same thing by calling a >> > function from within the function that requires the user to be logged >> > in. >> > >> > def change_pass(): >> > check_user_logged_in() >> > ... more stuff here... >> > >> > is less complex (and therefore preferable) than: >> > >> > @check_user_logged_in >> > def change_pass(): >> > ... more stuff here... >> > >> > An important principle in engineering is that you should always strive >> > to make your design as simple as possible. If you have two equal >> > designs, you should always choose the one that is simpler because >> > simple things are easier to understand than complex things. >> >> I don't see the complexity in this case - both are a single line of >> code. Any internal complexity is hidden by the language. In fact, I > > "Hiding" doesn't reduce complexity, quite the opposite. >> consider the decorated function simpler than the other: its body >> represents exactly what the function does, without any distracting >> precondition calls. > > Think about how the decorator is implemented. It is a high order > function, taking a function and returning a new function. Something > like this: > > def check_user_logged_in(func): > def f(*args, **kwargs): > if global_state.the_user.is_logged_in: > return func(*args, **kwargs) > return show_login_page() > return f I think there is a semantic problem, perhaps we are not talking about the same thing. I'm considering the software complexity AS PERCEIVED BY THE PROGRAMMER, looking at the interactions between a program and a programmer who is working on some task; some people would say "cognitive complexity" to make it clear. Coupling and cohesion are some of its main attributes. I'm *not* talking about "algorithmic complexity", by example; nor any other aspect of complexity. Given this frame, I think you may understand why "hiding details" reduces complexity: the programmer does not have to think/worry about those particular items. Which API is more complex: one in which you can play a movie with just a single call like PlayMovie(Title), or one on which you must call a zillion functions to firtly initialize the stream format, configure the display, disable undesired user interfase elements, locate the movie file, load it in chunks, etc.? The first one is certainly much simpler to use (simpler = less complex), and maybe internally it calls the same functions as the second one, but nobody cares. Let's look at a generator. Internally it's a complex thing: it has to keep its execution state, the stack frames, local and global variables... But all that internal complexity is hidden by the language, and the Python programmer only sees a continuable function. And that's great. Suppose you have a producer bound to a consumer - they are tightly coupled and that makes the code too complex. Using a generator you can decouple consumer from producer, making the code a lot simpler. What's important is how the programmer sees it; it doesn't matter if the underlying structures and tools were hard to program; it does matter if *now*, using those structures and tools, the programmer can write simpler and more comprehensible code (and faster, and less likely to contain bugs). Back to your example, the fact that a decorator builds a higher order function, does NOT make it more complex - because the programmer does not see that. In fact, hiding the details makes it simpler. >> The decorator has some advantages: can have syntax support on your >> editor, can perform some registering/logging, it's even easier to >> quickly check visually if it's here. > > The decorator has just as many disadvantages. For example, what if you > want to redirect back to the change_pass page once the user has > pressed the Login button on the login_page? Or if you want to show > different login pages depending on user properties? How much control > flow do you really want to "hide" in your decorator? I can't see the disadvantages; using a decorator, you have available the function being decorated, and you can manipulate it as you wish. -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list