I just read the plan for decorators in Python 2.4, and I'm surprised to see no discussion of what seems to me the cleanest answer, to optionally write function definitions as assignments: foo=def(a,b): print a,b which allows trivial modification by decorators: bar1=staticmethod(def(a, b)): print a,b bar2=accepts(int, int, staticmethod(def(a, b))): print a,b bar3=adddocstring("this function prints its arguments", trace(def(a,b))): print a,b It makes it clear in which order the functions are called, unlike with the @ syntax, and what their arguments are. It has obvious line-break syntax. You can include arguments to the functions without having to curry them, making it much easier to write one's own decorator functions. Both the "def foo(...):" and "foo=def(...):" syntaxes would be accepted. I don't think there's any ambiguity. Classes would work the same way: SimpleClass=class(object): ... FancyClass=tweakclass(class(object)): ... Among other things, by unifying assignment and definition, it makes the semantics of function name (re-)binding obvious, so if you read code like, foo=def(a,b): print "goodbye" foo2=foo foo=def(c,b): print "hello" foo() foo2() it's obvious what will happen, while with the current syntax people familiar with other languages would expect an error or undefined behavior. It also works nicely for nested functions, making it obvious that it binds in the local namespace just like regular assignment. Making function definition just another sort of assignment emphasizes the dynamic nature of the language, and will encourage people to treat functions as first-class data types. The precise rule is that when there is a def or class in a line (and there can be only one) there must be a colon and a block following. You could even use this to provide a more general alternative to lambda, allowing multi-statement lambdas: x=map(def(a), [1,2,3]): b=sin(a) return b*3 assert x == [3*sin(1), 3*sin(2), 3*sin(3)] though this might not be something to encourage. And it makes stashing functions somewhere easy: atexit.register(def()): print "exiting..." converters.append(def(a)): ... convert something ... Etags doesn't currently grok this syntax, but it should anyway because it would also help tag global variables. It's easy to implement with a regex, something like /^\s*(\w+)\s*=.*\bdef\b/ One bummer is that it may be more difficult to set the __name__ property of a function. -- Trevor Blackwell tlb at tlb.org (650) 776-7870
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4