Alex Martelli wrote: > Joe Marshall <[EMAIL PROTECTED]> wrote: > ... > > The problem is that a `name' is a mapping from a symbolic identifier to > > an object and that this mapping must either be global (with the > > attendant name collision issues) or within a context (with the > > attendant question of `in which context'). > > Why is that a problem? Even for so-called "global" names, Python > supports a structured, hierarchical namespace, so there can never be any > collision betwen the "globals" of distinct modules (including modules > which happen to have the same name but live in distinct packages or > subpackages) -- I did mention that names could usefully be displayed in > some strcutured form such as apackage.somemodule.thefunction but perhaps > I was too tangential about it;-).
Can you refer to inner functions from the global context? Suppose I have this Python code: def make_adder(x): def adder_func(y): sum = x + y return sum return adder_func Can I refer to the inner adder_func in any meaningful way? > > > > Matthias Felleisen once suggested that *every* internal function should > > be named. I just said `continuations'. He immediately amended his > > statement with `except those'. > > If I used continuations (I assume you mean in the call/cc sense rather > than some in which I'm not familiar?) I might feel the same way, or not, > but I don't (alas), so I can't really argue the point either way for > lack of real-world experience. I meant continuations as in the receiver function in continuation-passing-style. If you have a function that has to act differently in response to certain conditions, and you want to parameterize the behavior, then one possibility is to pass one or more thunks to the function in addition to the normal arguments. The function acts by selecting and invoking one of the thunks. A classic example is table lookup. It is often the case you wish to proceed differently depending upon whether a key exists in a table or not. There are several ways to provide this functionality. One is to have a separate `key-exists?' predicate. Another is to have a special return value for `key not found'. Another is to throw an exception when a key is not found. There are obvious advantages and drawbacks to all of these methods. By using continuation-passing-style, we can parameterize how the table lookup proceeds once it determines whether or not the key is found. We have the lookup procedure take two thunks in addition to the key. If the key is found, the first thunk is invoked on the associated value. If the key is not found, the second thunk is invoked. We can subsume all the previous behaviors: (define (key-exists? key table) (lookup key table (lambda (value) #t) ;; if found, ignore value, return true (lambda () #f))) ;; if not found, return false. (define (option1 key table) (lookup key table (lambda (value) value) (lambda () 'key-not-found))) (define (option2 key table) (lookup key table (lambda (value) value) (lambda () (raise 'key-not-found-exception)))) (define (option3 key table default-value) (lookup key table (lambda (value) value) (lambda () default-value))) The unnamed functions act in this regard much like a `local label'. We wrap two chunks of code in a lambda and the lookup function `jumps' to the appropriate chunk. (If the compiler knows about thunks, the generated assembly code really will have local labels and jump instructions. It can be quite efficient.) This may look odd and cumbersome, but with a little practice the lambdas fade into the background and it becomes easy to read. My point with Matthias, however, was that defining all these continuations (the thunks) as named internal functions was not only cumbersome, but it obscured the control flow. Notice: (define (named-option3 key table default-value) (define (if-found value) value) (define (if-not-found) default-value) (lookup key table if-found if-not-found)) When we enter the function, we skip down to the bottom (past the internal definitions) to run lookup, which transfers control to a function defined earlier in the code. There are many reasons to avoid this style in Python, so this probably won't win you over, but my point is that there are times where anonymous functions have an advantage over the named alternative and that disallowing anonymous functions can be as cumbersome as disallowing anonymous integers. -- http://mail.python.org/mailman/listinfo/python-list