keyword for introducing generators

I'm sure this has been suggested before, but I just spent two days trying to figure out why a method wasn't being called only to find that I'd accidentally pasted a yield into the function. What is the argument against a different keyword for introducing generator functions/methods? If it's backward compatibility, then my suggestion to have a from __future__ and then make it real in Python 4. Neil

On Sun, Aug 17, 2014 at 7:46 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
There are quite a few changes to a function based on its body, like how the presence of assignment causes a name to be local unless explicitly declared otherwise. It's not necessary to predeclare everything. But if you're having trouble with a function like that, maybe a little decorator would help: def announce(f): def inner(*a,**kw): print("Calling:",f.__name__) ret=f(*a,**kw) print("Return value is a",type(ret)) return ret return inner Decorate a function @announce, and it'll tell you (a) that it's being called, and (b) what type its return value is. If that's a generator, well, there's your answer. ChrisA

This is only a good solution once I realize that the method isn't being called after which, I now know what to look for. The whole point is to defensively design a language so that I don't get into this problem in the first place. Since I always know when I'm writing a function whether I want it to be automatically generator-returning using the yield keyword or not, then why not let me specify that? That way if the function gets long and I forget yield or accidentally include it, I get a reasonable error. You're right that it's not necessary to predeclare everything, but a different keyword is hardly more work. (And with respect to local, nonlocal and global variables, we often do predeclare those.) Best, Neil On Sat, Aug 16, 2014 at 5:55 PM, Chris Angelico <rosuav@gmail.com> wrote:

On Aug 16, 2014, at 14:55, Chris Angelico <rosuav@gmail.com> wrote:
I think it would be both simpler and more useful for him to write: def generator(f): assert inspect.isgeneratorfunction(f) return f def function(f): asset not inspect.isgeneratorfunction(f) return f Then he can just declare his functions as @generator or @function as appropriate and get an error at definition time if he accidentally got something wrong.

On Sat, Aug 16, 2014 at 3:17 PM, Jonas Wielicki <j.wielicki@sotecware.net> wrote:
A linter should be able to figure this out. For example, mypy will insist that a generator has a return type of Iterable[...]. So maybe you won't have to wait for Python 4; if the mypy proposal goes forward you will be able to use type annotations to distinguish generators. -- --Guido van Rossum (python.org/~guido)

Sorry for the late reply. If I mark a function as returning Iterable, the linter can check that I use yield in the function, but if I don't mark the function as returning anything, the linter should also check that I didn't accidentally use yield, which is the time-consuming bug that we're talking about. So this works for me. Best, Neil On Sat, Aug 16, 2014 at 7:42 PM, Guido van Rossum <guido@python.org> wrote:

On Sun, Aug 17, 2014 at 7:46 AM, Neil Girdhar <mistersheik@gmail.com> wrote:
There are quite a few changes to a function based on its body, like how the presence of assignment causes a name to be local unless explicitly declared otherwise. It's not necessary to predeclare everything. But if you're having trouble with a function like that, maybe a little decorator would help: def announce(f): def inner(*a,**kw): print("Calling:",f.__name__) ret=f(*a,**kw) print("Return value is a",type(ret)) return ret return inner Decorate a function @announce, and it'll tell you (a) that it's being called, and (b) what type its return value is. If that's a generator, well, there's your answer. ChrisA

This is only a good solution once I realize that the method isn't being called after which, I now know what to look for. The whole point is to defensively design a language so that I don't get into this problem in the first place. Since I always know when I'm writing a function whether I want it to be automatically generator-returning using the yield keyword or not, then why not let me specify that? That way if the function gets long and I forget yield or accidentally include it, I get a reasonable error. You're right that it's not necessary to predeclare everything, but a different keyword is hardly more work. (And with respect to local, nonlocal and global variables, we often do predeclare those.) Best, Neil On Sat, Aug 16, 2014 at 5:55 PM, Chris Angelico <rosuav@gmail.com> wrote:

On Aug 16, 2014, at 14:55, Chris Angelico <rosuav@gmail.com> wrote:
I think it would be both simpler and more useful for him to write: def generator(f): assert inspect.isgeneratorfunction(f) return f def function(f): asset not inspect.isgeneratorfunction(f) return f Then he can just declare his functions as @generator or @function as appropriate and get an error at definition time if he accidentally got something wrong.

On Sat, Aug 16, 2014 at 3:17 PM, Jonas Wielicki <j.wielicki@sotecware.net> wrote:
A linter should be able to figure this out. For example, mypy will insist that a generator has a return type of Iterable[...]. So maybe you won't have to wait for Python 4; if the mypy proposal goes forward you will be able to use type annotations to distinguish generators. -- --Guido van Rossum (python.org/~guido)

Sorry for the late reply. If I mark a function as returning Iterable, the linter can check that I use yield in the function, but if I don't mark the function as returning anything, the linter should also check that I didn't accidentally use yield, which is the time-consuming bug that we're talking about. So this works for me. Best, Neil On Sat, Aug 16, 2014 at 7:42 PM, Guido van Rossum <guido@python.org> wrote:
participants (5)
-
Andrew Barnert
-
Chris Angelico
-
Guido van Rossum
-
Jonas Wielicki
-
Neil Girdhar