Joe Marshall <[EMAIL PROTECTED]> wrote: > 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?
You can refer to one instance/closure (which make_adder returns), of course -- you can't refer to the def statement itself (but that's a statement, ready to create a function/closure each time it executes, not a function, thus, not an object) except through introspection. Maybe I don't understand what you mean by this question... > > 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 Ah, OK, I would refer to this as "callbacks", since no call-with-continuation is involved, just ordinary function calls; your use case, while pretty alien to Python's typical style, isn't all that different from other uses of callbacks which _are_ very popular in Python (cfr the key= argument to the sort methods of list for a typical example). I would guess that callbacks of all kinds (with absolutely trivial functions) is the one use case which swayed Guido to keep lambda (strictly limited to just one expression -- anything more is presumably worth naming), as well as to add an if/else ternary-operator. I still disagree deeply, as you guessed I would -- if I had to work with a framework using callbacks in your style, I'd name my callbacks, and I wish Python's functools module provided for the elementary cases, such as: def constant(k): def ignore_args(*a): return k return ignore_args def identity(v): return v and so on -- I find, for example, that to translate your > (define (option3 key table default-value) > (lookup key table > (lambda (value) value) > (lambda () default-value))) I prefer to use: def option3(key, table, default_value): return lookup(key, table, identity, constant(default_value)) as being more readable than: def option3(key, table, default_value): return lookup(key, table, lambda v: v, lambda: default_value) After all, if I have in >1 place in my code the construct "lambda v: v" (and if I'm using a framework that requires a lot of function passing I'm likely to be!), the "Don't Repeat Yourself" (DRY) principle suggests expressing the construct *ONCE*, naming it, and using the name. By providing unnamed functions, the language aids and abets violations of DRY, while having the library provide named elementary functions (in the already-existing appropriate module) DRY is reinforced and strongly supported, which, IMHO, is a very good thing. Alex -- http://mail.python.org/mailman/listinfo/python-list