Steve R. Hastings wrote: > On Fri, 05 May 2006 21:16:50 -0400, Ken Tilton wrote: > > The upshot of > > what he wrote is that it would be really hard to make semantically > > meaningful indentation work with lambda. > > Pretty much correct. The complete thought was that it would be painful > all out of proportion to the benefit. > > See, you don't need multi-line lambda, because you can do this: > > > def make_adder(x): > def adder_func(y): > sum = x + y > return sum > return adder_func
Now imagine you had to do this with every object. def add_five(x) # return x + 5 <-- anonymous integer literal, not allowed!!! five = 5 # define it first return x + five Think about the ramifications of every object having to have a name in some environment, so that at the leaves of all expressions, only names appear, and literals can only be used in definitions of names. Also, what happens in the caller who invokes make_adder? Something like this: adder = make_adder(42) Or perhaps even something like this make_adder(2)(3) --> 5 Look, here the function has no name. Why is that allowed? If anonymous functions are undesireable, shouldn't there be a requirement that the result of make_adder has to be bound to a name, and then the name must be used? > Note that make_adder() doesn't use lambda, and yet it makes a custom > function with more than one line. Indented, even. That function is not exactly custom. What is custom are the environment bindings that it captures. The code body comes from the program itself. What about actually creating the source code of a function at run-time and compiling it? (let ((source-code (list 'lambda (list 'x 'y) ...))) (compile nil source-code)) Here, we are applying the compiler (available at run-time) to syntax which represents a function. The compiler analyzes the syntax and compiles the function for us, giving us an object that can be called. Without that syntax which can represent a function, what do you pass to the compiler? If we didn't have lambda in Lisp, we could still take advantage of the fact that the compiler can also take an interpreted function object and compile that, rather than source code. So we could put together an expression which looks like this: (flet ((some-name (x y) ...)) #'some-name) We could EVAL this expression, which would give us a function object, which can then be passed to COMPILE. So we have to involve the evaluator in addition to the compiler, and it only works because the compiler is flexible enough to accept function objects in addition to source code. > No; lambda is a bit more convenient. But this doesn't seem like a very > big issue worth a flame war. If GvR says multi-line lambda would make > the lexer more complicated and he doesn't think it's worth all the effort, > I don't see any need to argue about it. I.e. GvR is the supreme authority. If GvR rationalizes something as being good for himself, that's good enough for me and everyone else. > I won't say more, since Alex Martelli already pointed out that Google is > doing big things with Python and it seems to scale well for them. That's pretty amazing for something that doesn't even have a native compiler, and big mutexes in its intepreter core. Look at "docs.python.org" in section 8.1 en titled "Thread State and the Global Interpreter Lock": "The Python interpreter is not fully thread safe. In order to support multi-threaded Python programs, there's a global lock that must be held by the current thread before it can safely access Python objects. Without the lock, even the simplest operations could cause problems in a multi-threaded program: for example, when two threads simultaneously increment the reference count of the same object, the reference count could end up being incremented only once instead of twice. Therefore, the rule exists that only the thread that has acquired the global interpreter lock may operate on Python objects or call Python/C API functions. In order to support multi-threaded Python programs, the interpreter regularly releases and reacquires the lock -- by default, every 100 bytecode instructions (this can be changed with sys.setcheckinterval())." That doesn't mean you can't develop scalable solutions to all kinds of problems using Python. But it does mean that the scalability of the overall solution comes from architectural details that are not related to Python itself. Like, say, having lots of machines linked by a fast network, working on problems that decompose along those lines quite nicely. -- http://mail.python.org/mailman/listinfo/python-list