Re: [Python-ideas] [Python-3000] PEP 3107 Function Annotations: overloadable ->
![](https://secure.gravatar.com/avatar/40190c456131372a6346401f6f35dd74.jpg?s=120&d=mm&r=g)
To Tony and Kay, my short answer is: use __returns__ . Moving to python-ideas as per Guido's request: "Guido van Rossum" <guido@python.org> wrote: > This is sufficiently controversial that I believe it ought to go to > python-ideas first. If it comes to a PEP it should be a separate one > from PEP 3107. > On 1/1/07, Talin <talin@acm.org> wrote: > > Tony Lownds wrote: > > >> From: Tony Lownds <tony@pagedna.com> > > > What do people here think? > > 1) Normally, we don't name operators based on their shape - we don't > > call '/' the __slash__ operator, for example, nor do we call '|' the > > "__vbar__" operator. Certainly, but those two operators, and basically every other operator used in Python have long-standing semantics in basically every language that Python is even remotely related to. > > 2) I think that all operators should have a "suggested semantic". When > > someone overloads the '+' operator, its a good bet that the meaning of > > the overload has something to do with addition or accumulation in a > > general sense. This won't *always* be true, but it will be true often > > enough. I don't buy your "suggested semantic" argument. And even if I did, operator overloading allows people to choose the semantics of operations for themselves; suggesting a semantic for an operation would be a set of documentation that would never be read, and if it was read, ignored. > > But an arbitrary operator with no guidelines as to what it means is > > anyone's guess; It means that when we see a '->' operator embedded in > > the code, we have no idea what is being said. Ahh, but in this case there is precisely one place where the '->' operator is planned on being found for Py3k: def <name>(<arglist with or without annotations>) -> <annotation>: <body> In that sense, we don't need a fcn_obj.__becomes__(<annotation>) method, and that wasn't what the discussion was about, it was "what should the attribute be called for this already agreed upon *function annotation*?". Now, because this *particular* annotation was created to allow for the annotation of "returns", I agree with Kay's last suggestion, the attribute should be called __returns__, as that is *exactly* what the annotation was meant to convey. > > From an HCI perspective, punctuation symbols improve code readability > > only if their meanings are familiar to the reader; An operator whose > > meaning is constantly changing is a hindrance to readability rather than > > a help. Claiming "we want a particular operation to always refer to the same method/attribute" is only applicable if a particular operation has a chance of meaning more than one thing. Currently it means *exactly* one thing in the context of Python, 'this function returns X', so in my opinion, your argument isn't applicable. If you can manage to convince more people in python-ideas of arbitrary operations (as per your previous message(s) on the subject), and/or you can convince Guido to say "I would like more operations in Python", then your argument is applicable. However, I don't believe that you will be able to convince Guido that the large set of operations that you have previously posted about would be a good idea, and I certainly don't believe it would happen with sufficient time to make it into the first Py3k release. - Josiah
![](https://secure.gravatar.com/avatar/c3eddec3d2fbdeb60b81f8fcfb6c5d23.jpg?s=120&d=mm&r=g)
Josiah Carlson wrote: > To Tony and Kay, my short answer is: use __returns__ . > > Moving to python-ideas as per Guido's request: > > "Guido van Rossum" <guido@python.org> wrote: >> This is sufficiently controversial that I believe it ought to go to >> python-ideas first. If it comes to a PEP it should be a separate one >> from PEP 3107. > >> On 1/1/07, Talin <talin@acm.org> wrote: >>> Tony Lownds wrote: >>>>> From: Tony Lownds <tony@pagedna.com> >>>> What do people here think? >>> 1) Normally, we don't name operators based on their shape - we don't >>> call '/' the __slash__ operator, for example, nor do we call '|' the >>> "__vbar__" operator. > > Certainly, but those two operators, and basically every other operator > used in Python have long-standing semantics in basically every language > that Python is even remotely related to. > > >>> 2) I think that all operators should have a "suggested semantic". When >>> someone overloads the '+' operator, its a good bet that the meaning of >>> the overload has something to do with addition or accumulation in a >>> general sense. This won't *always* be true, but it will be true often >>> enough. > > I don't buy your "suggested semantic" argument. And even if I did, > operator overloading allows people to choose the semantics of operations > for themselves; suggesting a semantic for an operation would be a set of > documentation that would never be read, and if it was read, ignored. > > >>> But an arbitrary operator with no guidelines as to what it means is >>> anyone's guess; It means that when we see a '->' operator embedded in >>> the code, we have no idea what is being said. > > Ahh, but in this case there is precisely one place where the '->' > operator is planned on being found for Py3k: > > def <name>(<arglist with or without annotations>) -> <annotation>: > <body> > > In that sense, we don't need a fcn_obj.__becomes__(<annotation>) method, > and that wasn't what the discussion was about, it was "what should the > attribute be called for this already agreed upon *function annotation*?". > > Now, because this *particular* annotation was created to allow for the > annotation of "returns", I agree with Kay's last suggestion, the > attribute should be called __returns__, as that is *exactly* what the > annotation was meant to convey. > > >>> From an HCI perspective, punctuation symbols improve code readability >>> only if their meanings are familiar to the reader; An operator whose >>> meaning is constantly changing is a hindrance to readability rather than >>> a help. > > Claiming "we want a particular operation to always refer to the same > method/attribute" is only applicable if a particular operation has a > chance of meaning more than one thing. Currently it means *exactly* one > thing in the context of Python, 'this function returns X', so in my > opinion, your argument isn't applicable. > > If you can manage to convince more people in python-ideas of arbitrary > operations (as per your previous message(s) on the subject), and/or you > can convince Guido to say "I would like more operations in Python", then > your argument is applicable. > > However, I don't believe that you will be able to convince Guido that > the large set of operations that you have previously posted about would > be a good idea, and I certainly don't believe it would happen with > sufficient time to make it into the first Py3k release. > > > - Josiah Sorry, I'm a habitual generalizer :) Anyway, I'm not going to push on this one any further, neither here nor in python-ideas. There are more important things to work on. -- Talin
![](https://secure.gravatar.com/avatar/865d8ec43f5dfdf54365b2293c53cc3f.jpg?s=120&d=mm&r=g)
On Jan 1, 2007, at 2:03 PM, Josiah Carlson wrote:
To Tony and Kay, my short answer is: use __returns__ .
Thanks Talin's arguments for a consistent semantic make me think that __implies__ would be a bad idea (among other things). Is anyone against "->" overloadable as __returns__ /__rreturns__ with no semantics for existing types? -Tony
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On 1/1/07, Tony Lownds <tony@pagedna.com> wrote:
Is anyone against "->" overloadable as __returns__ /__rreturns__ with no semantics for existing types?
I suggest that you question *really* *hard* whether it's worth it. We'd be introducing two very different syntactic uses for '->'. I chose this operator to signify function return annotation specifically because it *does't* have another meaning in Python. (My first choice would've been ':', which is mostly a delimiter that derives its meaning from context, like ',', but that would've introduced too much syntactic ambiguity. -- --Guido van Rossum (home page: http://www.python.org/~guido/)
![](https://secure.gravatar.com/avatar/40190c456131372a6346401f6f35dd74.jpg?s=120&d=mm&r=g)
"Guido van Rossum" <guido@python.org> wrote:
On 1/1/07, Tony Lownds <tony@pagedna.com> wrote:
Is anyone against "->" overloadable as __returns__ /__rreturns__ with no semantics for existing types?
I suggest that you question *really* *hard* whether it's worth it. We'd be introducing two very different syntactic uses for '->'. I chose this operator to signify function return annotation specifically because it *does't* have another meaning in Python. (My first choice would've been ':', which is mostly a delimiter that derives its meaning from context, like ',', but that would've introduced too much syntactic ambiguity.
Just to clarify, the only place '->' is allowable is in the case of function annotations... def <name>(<args...>) -> <annotation>: <body> Given a reading of version 53169 of PEP 3107, I see no reason to even offer a __returns__ attribute, automatic method call, etc. PEP 3107 already defines the annotation to be specified as a dictionary of named argument names, with a key of 'return' for the annotation of the return annotation. Is there any reason why this isn't sufficient? Even in the context of the signature PEP 362, there is no need for __returns__, as an annotation-consuming library would check the signature object for argument annotations, and the func_annotations dictionary for the 'return' key for any return annotations. - Josiah
![](https://secure.gravatar.com/avatar/865d8ec43f5dfdf54365b2293c53cc3f.jpg?s=120&d=mm&r=g)
On Jan 1, 2007, at 5:39 PM, Josiah Carlson wrote:
Given a reading of version 53169 of PEP 3107, I see no reason to even offer a __returns__ attribute, automatic method call, etc. PEP 3107 already defines the annotation to be specified as a dictionary of named argument names, with a key of 'return' for the annotation of the return annotation. Is there any reason why this isn't sufficient?
Even in the context of the signature PEP 362, there is no need for __returns__, as an annotation-consuming library would check the signature object for argument annotations, and the func_annotations dictionary for the 'return' key for any return annotations.
Something got lost in the movement between lists... __returns__ wasn't going to supplant or alter func_annotations or PEP 362 in any way. __returns__ was proposed as the special method attached to a new operator (->). That operator could be used to write expressions that look like a function signature. Here's Kay's original email. http://mail.python.org/pipermail/python-list/2007-January/420774.html -Tony
![](https://secure.gravatar.com/avatar/40190c456131372a6346401f6f35dd74.jpg?s=120&d=mm&r=g)
Tony Lownds <tony@pagedna.com> wrote:
On Jan 1, 2007, at 5:39 PM, Josiah Carlson wrote:
Given a reading of version 53169 of PEP 3107, I see no reason to even offer a __returns__ attribute, automatic method call, etc. PEP 3107 already defines the annotation to be specified as a dictionary of named argument names, with a key of 'return' for the annotation of the return annotation. Is there any reason why this isn't sufficient?
Even in the context of the signature PEP 362, there is no need for __returns__, as an annotation-consuming library would check the signature object for argument annotations, and the func_annotations dictionary for the 'return' key for any return annotations.
Something got lost in the movement between lists... __returns__ wasn't going to supplant or alter func_annotations or PEP 362 in any way.
__returns__ was proposed as the special method attached to a new operator (->). That operator could be used to write expressions that look like a function signature.
Here's Kay's original email.
http://mail.python.org/pipermail/python-list/2007-January/420774.html
-1 on the -> operator as specified in the email you link. There is no reason to add aribtrary operators for call-site annotations. PEP 3107 has already defined the syntax for function definition site annotations as follows... def name(argument=default:annotation) -> annotation: body While PEP 3107 has not been formally accepted (according to the web page), the ideas contained received general approval from more or less everyone involved in the py3k discussion, or at least more or less everyone who has written and/or consumed annotations in the past. The mail you link, talks about an arbitrary -> operator for call-site annotations. Without seeing actual use-cases where a -> operator would be useful in the real-world, I can't help but be -1 on the -> operator and -1 on the __returns__ method. Use-case(s) before syntax and semantics, - Josiah
![](https://secure.gravatar.com/avatar/80c29b46b1029609a28cb8e110d88702.jpg?s=120&d=mm&r=g)
Josiah Carlson schrieb:
Tony Lownds <tony@pagedna.com> wrote:
On Jan 1, 2007, at 5:39 PM, Josiah Carlson wrote:
Given a reading of version 53169 of PEP 3107, I see no reason to even offer a __returns__ attribute, automatic method call, etc. PEP 3107 already defines the annotation to be specified as a dictionary of named argument names, with a key of 'return' for the annotation of the return annotation. Is there any reason why this isn't sufficient?
Even in the context of the signature PEP 362, there is no need for __returns__, as an annotation-consuming library would check the signature object for argument annotations, and the func_annotations dictionary for the 'return' key for any return annotations.
Something got lost in the movement between lists... __returns__ wasn't going to supplant or alter func_annotations or PEP 362 in any way.
__returns__ was proposed as the special method attached to a new operator (->). That operator could be used to write expressions that look like a function signature.
Here's Kay's original email.
http://mail.python.org/pipermail/python-list/2007-January/420774.html
-1 on the -> operator as specified in the email you link. There is no reason to add aribtrary operators for call-site annotations. PEP 3107 has already defined the syntax for function definition site annotations as follows...
def name(argument=default:annotation) -> annotation: body
If a function consumes or returns another function, it is quite natural to check against the function type ( at least for certain usefull annotation handlers ). Some experts call those "higher order functions". Programmers have found those in Pythons __builtins__ module. Others have guessed that decorators could be HOF. I hope this is convenient enough for motivation. With current syntax one ends up defining function type annotations like this Function(int,str).returns(str) Function(int,str)*str (Function(int,str), str) "(int,str)->str" ... Maybe one can update PEP 8 for a recommendation, if there is just too much syntax angst for choosing the form Function(int, str)->str where wild hordes of Pythonistas might think about this as an implication - and are perfectly correct about it of course, at least according to Curry-Howard and any person, reading at least an introductory paper about type theory. The latter is also the reason why Tonys __implies__ proposal makes perfect sense to me. Regards and a happy new year, Kay
![](https://secure.gravatar.com/avatar/865d8ec43f5dfdf54365b2293c53cc3f.jpg?s=120&d=mm&r=g)
On Jan 1, 2007, at 10:34 PM, Josiah Carlson wrote:
-1 on the -> operator as specified in the email you link. There is no reason to add aribtrary operators for call-site annotations.
What was the arbitrary operator? -> is not arbitrary, and there was a reason given to add it.
PEP 3107 has already defined the syntax for function definition site annotations as follows...
def name(argument=default:annotation) -> annotation: body
You mean def name(argument:annotation=default)
The mail you link, talks about an arbitrary -> operator for call-site annotations. Without seeing actual use-cases where a -> operator would be useful in the real-world, I can't help but be -1 on the -> operator and -1 on the __returns__ method.
That email had a use case... The gain is being able to write def wrap(text: str, split: Function(str)-> list): instead of def wrap(text: str, split: Function(str) == list): or def wrap(text: str, split: Function(str, returns=list)): or one of the other methods that Kay came up with. -Tony
![](https://secure.gravatar.com/avatar/40190c456131372a6346401f6f35dd74.jpg?s=120&d=mm&r=g)
Tony Lownds <tony@pagedna.com> wrote:
On Jan 1, 2007, at 10:34 PM, Josiah Carlson wrote:
-1 on the -> operator as specified in the email you link. There is no reason to add aribtrary operators for call-site annotations.
What was the arbitrary operator? -> is not arbitrary, and there was a reason given to add it.
I misunderstood portions of the post.
PEP 3107 has already defined the syntax for function definition site annotations as follows...
def name(argument=default:annotation) -> annotation: body
You mean
def name(argument:annotation=default)
Thank you for the correction. Maybe I'm the only one, but I would prefer the default value to come before the annotation.
The mail you link, talks about an arbitrary -> operator for call-site annotations. Without seeing actual use-cases where a -> operator would be useful in the real-world, I can't help but be -1 on the -> operator and -1 on the __returns__ method.
That email had a use case... The gain is being able to write
def wrap(text: str, split: Function(str)-> list):
instead of
def wrap(text: str, split: Function(str) == list):
or
def wrap(text: str, split: Function(str, returns=list)):
or one of the other methods that Kay came up with.
Kay's mail specified: maptype = Function( Function(object)->object, list) -> list That looks to me like the -> operator being used anywhere the user desires. With your examples above, I see the use-case, but I'm still -1 (for the same reasons). For other reasons to be -1 on ->, we can look at how it would be abused to violate the one obvious way to do things... Stack() -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 t = Tree() t -> (t -> (1,2), t -> (3,4)) Or for a concrete example... class mylist(list): def __returns__(self, arg): self.append(arg) return self mylist() -> 1 -> 2 -> 3 -> 4 -> 5 Right now those things aren't done because the punctuation for doing it isn't as natural as -> would be. - Josiah
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On 1/2/07, Josiah Carlson <jcarlson@uci.edu> wrote:
PEP 3107 has already defined the syntax for function definition site annotations as follows...
def name(argument=default:annotation) -> annotation: body
You mean
def name(argument:annotation=default)
Thank you for the correction. Maybe I'm the only one, but I would prefer the default value to come before the annotation.
You're about a year and a half too late with this objection. And anyway, I strongly favor putting the annotation first; that's how it is in other languages from which Python has borrowed before, e.g. Modula-3. Regarding the status of the PEP: I am mostly waiting for the wording to improve, e.g. not use examples that suggest this will have type checking semantics by default. I am +1 on the syntax used in the PEP, since it is what I have been proposing for a long time. I am against more additions like an '->' operator or attribute annotations or anything else at this point, at least until there has been actual experience with using the implementation as-is. (And yes, I have seen the use case, and remain unconvinced. Not every use case deserves new syntax.) -- --Guido van Rossum (home page: http://www.python.org/~guido/)
participants (6)
-
Guido van Rossum
-
Josiah Carlson
-
Kay Schluehr
-
Talin
-
Tony Lownds
-
Tony Lownds