On Sat, 12 Mar 2005, Josiah Carlson wrote:
I say it is magical. Why? The way you propose it, 'yield' becomes an infix operator, with the name provided on the left being assigned a value produced by something that isn't explicitly called, referenced, or otherwise, by the right. In fact, I would say, it would be akin to the calling code modifying gen.gi_frame._f_locals directly. Such "action at a distance", from what I understand, is wholly frowned upon in Python. There also does not exist any other infix operator that does such a thing (=, +=, ... assign values, but where the data comes from is obvious).
Bad things to me (so far): 1. Assignment is not obvious. 2. Where data comes from is not obvious. 3. Action at a distance like nothing else in Python. 4. No non-'=' operator assigns to a local namespace.
If it is too much action at a distance, one could also use the syntax "a = yield b", as has been suggested before, but I preferred it without the '='. With the '=', I don't see how it is any more action at a distance than "a = yield_func(b)" or "for i in f()". In all of these cases, values are being passed when the scope is changing.
If you want to argue that both of these syntaxes are too ugly to be allowed, then ok.
Or you could even use a class instance.
class foo: def pickled_file(self, name): f = open(name, 'r') yield pickle.load(f) f.close() f = open(name, 'w') pickle.dump(self.l, f) f.close()
fi = foo() for l in fi.pickled_file('greetings.pickle'): l.append('hello') l.append('howdy') fi.l = l
If you can call the function, there is always a shared namespace. It may not be obvious (you may need to place the function as a method of an instance), but it is still there.
The disadvantage of this method is that it is not clear where the self.l values is coming from just by reading the generator method definition. If it is coming from the code block, why not be able to explicity write it that way? Similarly, "continue l" explicitly shows that you are passing a value back to the generator.
Hrm, not good enough? Use a Queue, or use another variable in a namespace accessable to both your function and your loop.
Again, I entirely realize it's possible to do these things now, but that is not the point.
The point of your proposed syntax is to inject data back into a generator from an external namespace. Right?
The point is to inject data back into a generator in a clean, explicit way; I understand there are other ways in which one can already do this.
Furthermore, I would say that using yield semantics in the way that you are proposing, while being discussed in other locations (the IBM article on cooperative multithreading via generators springs to mind), is a clever hack, but not something that should be supported via syntax.
My impression is that being able to use yield in this way is one of the primary reasons for the success of ruby. Therefore, I do not see it as just a clever hack. It is a clean, explicity way to pass values when changing scope.
-Brian _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com