On Fri, 2011-10-14 at 13:20 +1000, Nick Coghlan wrote:
On Fri, Oct 14, 2011 at 11:10 AM, Ron Adam <ron3200@gmail.com> wrote:
Using your sort example. Lets say we rewrite that concept so it's more general using a decorator that can be reused. In this case, the key isn't the reusable part. It's the part that changes when we do sorts, so it's the part we put the decorator on to create a new sorted variation.
def sorted_with(key): def _(seq): return sorted(seq, key=key) return _
@sorted_with def key_sorted(item): return item.attr1, item.attr2
new_list = key_sorted(original_list)
Seriously? You're suggesting that mess of symbols and indentation as a good answer to the programming task "I want to sort the items in this sequence according to the values of attr1 and attr2"?
It's just a simple example of how you could do this. I'd probably just use a lmabda expression myself. I think the concept you are looking for is, how can you express a dependency in a natural order that also reads well. In this case, the end result cannot be built until all the parts are present. Class's are constructed top down. You create the framework and then fill in the parts. Functions (including decorators) are constructed from the inside out. That isn't always the easiest way to think about a problem. So a second separate goal is to have very concise one time expressions or statements.
Both of those work, but neither of them reaches the bar of "executable pseudocode" the language prides itself on.
PEP 403 also fails pretty abysmally (alas) on that front:
postdef sorted_list = sorted(original, key=sort_key) def sort_key(item): return item.attr1, item.attr2
The named function version fails because it gets things out of order:
Right and also, the 'postdef" keyword looks like it should result in a defined function, but it's actually a call here. Thats probably because I'm so used to seeing the 'def' in that way.
def sort_key(item): return item.attr1, item.attr2
sorted_list = sorted(original, key=sort_key)
That's more like pseudo code for "First, define a function that returns an object's attr1 and attr2 values. Than use that function to sort our list", a far cry from the originally requested operation.
I think "far cry" is over stating it a bit. I think this sort of issue is only a problem for very new programmers. Once they understand functions and how to used them together to make more complex things, they get used to this.
PEP 3150, on the other hand, actually gets close to achieving the pseudocode standard:
sorted_list = sorted(original, key=sort_key) given: def sort_key(item): return item.attr1, item.attr2
"Sort the items in this sequence according to the supplied key function. The key function returns the values of attr1 and attr2 for each item."
Right, we are constructing the framework first, and then the sub parts. But more specifically, we are suspending a piece of code, until it is safe to unsuspend it. I suppose you could use the '$' in some way to indicate a suspended bit of code. An 'S' with a line through it does map well to 'suspended'.
We can reuse the sorted_with decorator with as may key functions as we want. That reuse is an important feature of decorators.
No, no, no - this focus on reusability is *exactly* the problem. It's why callback programming in Python sucks - we force people to treat one-shot functions as if they were reusable ones, *even when those functions aren't going to be reused in any other statement*.
We have to use functions in call backs because an expression executes immediately rather than when it's needed. Also a call back usually needs some sort of input at the time it's used which isn't available before hand. Because python's functions are objects, it makes it much easier to do, So it's not really that bad once you figure it out. Non objective languages are more difficult in this respect.
You don't *care* about reusability in those cases - you care about handing the code you're currently writing over to be executed by some other piece of code
I think that is 'reusable'. And most likely it will be reused over and over if we are referring to a GUI. Some call back examples might be good. Cheers, Ron